LeetCode 周赛 316 题解

plus2047 于 2022-10-23 发布

第三题比第四题难一点,第四题三行代码秒杀。。

中国站传送门 国际站传送门

1. 判断两个事件是否存在冲突

image

一行代码。使用 Python 特有的连续比较运算符。

class Solution:
    def haveConflict(self, event1: List[str], event2: List[str]) -> bool:
        return event2[0] <= event1[0] <= event2[1] or event1[0] <= event2[0] <= event1[1]

2. 最大公因数等于 K 的子数组数目

image

本题数据规模不大,可以直接 O(n^2) 暴力求解。

class Solution:
    def subarrayGCD(self, nums: List[int], k: int) -> int:
        n, res = len(nums), 0
        for i in range(n):
            curr = nums[i]
            for j in range(i, n):
                curr = math.gcd(curr, nums[j])
                if curr == k:
                    res += 1
                elif curr < k:
                    break
        return res

顺便一提,最大公约数 gcd 运算如果视为二元运算符,具有交换律和结合律(本题最多使用到了结合律),能够使用很多类似于前缀和的技巧。

3. 使数组相等的最小开销

image

这道题目感觉比第四题要难一点,主要是 DP 实现时要小心一点。一些关键思路点如下:

class Solution:
    def minCost(self, nums: List[int], cost: List[int]) -> int:
        
        n = len(nums)
        pairs = sorted((x, y) for x, y in zip(nums, cost))

        suf, w = [0] * n, pairs[n - 1][1]
        for i in range(n - 2, -1, -1):
            suf[i] = suf[i + 1] + w * (pairs[i + 1][0] - pairs[i][0])
            w += pairs[i][1]
        
        pre, w = [0] * n, pairs[0][1]
        for i in range(1, n):
            pre[i] = pre[i - 1] + w * (pairs[i][0] - pairs[i - 1][0])
            w += pairs[i][1]
        
        return min(suf[i] + pre[i] for i in range(n))

这个题目看上去有点眼熟,应该是原题,但我不幸 WA 了一次。因为每当看到这个题目,我就会想起物理上重心的概念,然后试图使用数学方法直接求解,然后光荣翻车。。

我给出的这份代码并不是特别短,但它对称、好看!

4. 使数组相似的最少操作次数

image

感觉比第三题简单。本题约束「一定有解」降低了难度。关键思路:

于是最终代码只有三行。。

class Solution:
    def makeSimilar(self, nums: List[int], target: List[int]) -> int:
        nums = sorted(nums, key=lambda x: (x % 2, x))
        target = sorted(target, key=lambda x: (x % 2, x))
        return sum((x - y) // 2 for x, y in zip(nums, target) if x > y)