【LeetCode周赛】第191场周赛

一、5424. 数组中两元素的最大乘积

给你一个整数数组 nums,请你选择数组的两个不同下标 i 和 j,使 (nums[i]-1)*(nums[j]-1) 取得最大值。

请你计算并返回该式的最大值。

示例:

输入:nums = [3,4,5,2]
输出:12
解释:如果选择下标 i=1 和 j=2(下标从 0 开始),则可以获得最大值,(nums[1]-1)(nums[2]-1) = (4-1)(5-1) = 3*4 = 12 。

输入:nums = [1,5,4,5]
输出:16
解释:选择下标 i=1 和 j=3(下标从 0 开始),则可以获得最大值 (5-1)*(5-1) = 16 。

输入:nums = [3,7]
输出:12

提示:

  • 2 <= nums.length <= 500
  • 1 <= nums[i] <= 10^3

分析:

​ 由于题目给定了数组中元素皆为正数,所以只需要选出数组中最大与次大的元素即可。可以用排序来找出这两个元素,但是需要(O(nlgn))的时间复杂度。因此我们用一次遍历来找出这两个数,只需要(O(n))时间复杂度就可以解决问题。

代码:

class Solution:
    def maxProduct(self, nums: List[int]) -> int:
        fir_max, sec_max = 0, 0
        # 一次遍历找出最大值与次大值
        for num in nums:
            if num >= fir_max:
                sec_max = fir_max
                fir_max = num
            if sec_max <= num < fir_max:
                sec_max = num
        return (fir_max - 1) * (sec_max - 1)

二、5425. 切割后面积最大的蛋糕

矩形蛋糕的高度为 h 且宽度为 w,给你两个整数数组 horizontalCuts 和 verticalCuts,其中 horizontalCuts[i] 是从矩形蛋糕顶部到第 i 个水平切口的距离,类似地, verticalCuts[j] 是从矩形蛋糕的左侧到第 j 个竖直切口的距离。

请你按数组 horizontalCuts 和 verticalCuts 中提供的水平和竖直位置切割后,请你找出 面积最大 的那份蛋糕,并返回其 面积 。由于答案可能是一个很大的数字,因此需要将结果对 10^9 + 7 取余后返回。

示例:

输入:h = 5, w = 4, horizontalCuts = [1,2,4], verticalCuts = [1,3]
输出:4

输入:h = 5, w = 4, horizontalCuts = [3,1], verticalCuts = [1]
输出:6

输入:h = 5, w = 4, horizontalCuts = [3], verticalCuts = [3]
输出:9

分析:

​ 切割后面积最大的蛋糕,它的垂直与水平方向上的区间间隔的乘积一定是最大的。并且我们可以得出,垂直与水平方向上的区间分隔分别最大。这样只需要找到这两个最大区间分隔,返回它们的乘积即可。

代码:

class Solution:
    def maxArea(self, h: int, w: int, horizontalCuts: List[int], verticalCuts: List[int]) -> int:
        horizontalCuts = [0] + sorted(horizontalCuts) + [h]
        verticalCuts = [0] + sorted(verticalCuts) + [w]
        max_hon, max_vert = 0, 0
        for i in range(1, len(horizontalCuts)):
            max_hon = max(max_hon, horizontalCuts[i] - horizontalCuts[i - 1])
        for i in range(1, len(verticalCuts)):
            max_vert = max(max_vert, verticalCuts[i] - verticalCuts[i - 1])
        # 由于答案可能是一个很大的数字,因此需要将结果对 10^9 + 7 取余后返回。
        return (max_hon * max_vert) % 1000000007

三、5426. 重新规划路线

n 座城市,从 0 到 n-1 编号,其间共有 n-1 条路线。因此,要想在两座不同城市之间旅行只有唯一一条路线可供选择(路线网形成一颗树)。去年,交通运输部决定重新规划路线,以改变交通拥堵的状况。

路线用 connections 表示,其中 connections[i] = [a, b] 表示从城市 a 到 b 的一条有向路线。

今年,城市 0 将会举办一场大型比赛,很多游客都想前往城市 0 。

请你帮助重新规划路线方向,使每个城市都可以访问城市 0 。返回需要变更方向的最小路线数。

题目数据 保证 每个城市在重新规划路线方向后都能到达城市 0 。

示例:

输入:n = 6, connections = [[0,1],[1,3],[2,3],[4,0],[4,5]]
输出:3

输入:n = 5, connections = [[1,0],[1,2],[3,2],[3,4]]
输出:2

输入:n = 3, connections = [[1,0],[2,0]]
输出:0

分析:

​ 题目中所指的重新规划路线,其实只有更换方向这一种操作而已。并且题目保证每个城市在重新规划路线方向后都能达到城市0。因此我们可以认为,图中的结点实际上只有两种状态,一种是可以到达0,一种是经过一次翻转后可以到达0(即指向0或指向0的结点)。因此可以定义两个集合保存两个状态 connectedreversed。connected记录指向0的结点,reversed记录一次翻转就可以指向0的结点。遍历完成后,connected的长度应该与n相等,这样就符合题目要求:所有城市都可以访问城市0,reversed的长度就是本题答案。

代码:

class Solution:
    def minReorder(self, n: int, connections: List[List[int]]) -> int:
        res = 0
        connected = set()  # 记录已联通的结点
        connected.add(0)
        reversed = set()  # 记录只需要一次翻转就可以联通的结点,最后得到的长度就是题目答案
        
        while len(connected) < n:
            for city in connections:
                # 判断是否可以到达0
                if city[1] in connected:
                    connected.add(city[0])
            for city in connections:
                # 判断是否可以通过翻转来到达0
                if city[0] in connected and city[1] not in connected:
                    reversed.add(city[1])
            for i in reversed:
                connected.add(i)
        return len(reversed)

总结:

​ t4并没有做出来,这里只有链接,看看别人的题解:5427. 两个盒子中球的颜色数相同的概率

原文地址:https://www.cnblogs.com/enmac/p/13052740.html