LeetCode笔记:Weekly Contest 318

  • LeetCode笔记:Weekly Contest 318
    • 1. 题目一
      • 1. 解题思路
      • 2. 代码实现
    • 2. 题目二
      • 1. 解题思路
      • 2. 代码实现
    • 3. 题目三
      • 1. 解题思路
      • 2. 代码实现
    • 4. 题目四
      • 1. 解题思路
      • 2. 代码实现
  • 比赛链接:https://leetcode.com/contest/weekly-contest-318

1. 题目一

给出题目一的试题链接如下:

  • 2460. Apply Operations to an Array

1. 解题思路

这一题思路上很简单,就是用一个for循环按照题意逐一操作一下,然后重新排个序即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def applyOperations(self, nums: List[int]) -> List[int]:
        n = len(nums)
        for i in range(n-1):
            if nums[i] == nums[i+1]:
                nums[i] = nums[i] * 2
                nums[i+1] = 0
        res = [x for x in nums if x != 0] + [x for x in nums if x == 0]
        return res

提交代码评测得到:耗时123ms,占用内存14.1MB。

2. 题目二

给出题目二的试题链接如下:

  • 2461. Maximum Sum of Distinct Subarrays With Length K

1. 解题思路

这一题我的思路就是维护一个滑动窗口,然后查看长度为k的滑动窗口之中的unique元素个数是否为k,如果为k,计算其和值然后返回最大值。

2. 代码实现

给出python代码实现如下:

class Solution:
    def maximumSubarraySum(self, nums: List[int], k: int) -> int:
        n = len(nums)
        cnt = Counter(nums[:k])
        _sum = sum(nums[:k])
        res = 0 if len(cnt) < k else _sum
        for i in range(k, n):
            _sum += nums[i] - nums[i-k]
            cnt[nums[i]] += 1
            cnt[nums[i-k]] -= 1
            if cnt[nums[i-k]] == 0:
                cnt.pop(nums[i-k])
            if len(cnt) == k:
                res = max(res, _sum)
        return res

提交代码评测得到:耗时867ms,占用内存31.2MB。

3. 题目三

给出题目三的试题链接如下:

  • 2462. Total Cost to Hire K Workers

1. 解题思路

这一题同样我的思路是使用一个滑动窗口来控制每一轮当中的候选人池。

而这个候选人池子本身,我们使用一个堆排数组进行数据存储,从而可以以 O ( 1 ) O(1) O(1)的时间复杂度获取每一轮被雇佣的worker。

2. 代码实现

给出python代码实现如下:

class Solution:
    def totalCost(self, costs: List[int], k: int, candidates: int) -> int:
        n = len(costs)
        q = []
        for i in range(candidates):
            heapq.heappush(q, (costs.pop(), n-1-i))
        for i in range(candidates):
            if costs == []:
                break
            heapq.heappush(q, (costs.pop(0), i))

        res = 0
        lb, rb = candidates, n-1-candidates
        for i in range(k):
            x, idx = heapq.heappop(q)
            res += x
            if costs == []:
                continue
            if idx < lb:
                heapq.heappush(q, (costs.pop(0), lb))
                lb += 1
            else:
                heapq.heappush(q, (costs.pop(), rb))
                rb -= 1
        return res

提交代码评测得到:耗时2678ms,占用内存28.5MB。

4. 题目四

给出题目四的试题链接如下:

  • 2463. Minimum Total Distance Traveled

1. 解题思路

这一题我一开始没有搞定,后来是看了大佬们的解答之后才找到的思路,从而搞定的。

整体思路上来说,一个比较显然的点就是,机器人的终点之间不会存在交叉,也就是说,如果两个机器人都往左走,那么更右侧的机器人抵达的终点也一定更靠右侧,这个构造方式是显然的,因为如果存在交叉,那我们将他们的终点互换即可,不会影响总的距离。

因此,我们首先将机器人与工厂进行排序,然后只需要考察每一个工厂当中分配几个机器人抵达即可,而这个问题就可以比较简单的划归为一个动态规划的问题了。

2. 代码实现

给出python代码实现如下:

class Solution:
    def minimumTotalDistance(self, robot: List[int], factory: List[List[int]]) -> int:
        cnt = {k: v for k, v in factory}
        factory = sorted([x[0] for x in factory])     
        cnt = [cnt[x] for x in factory]
        robot = sorted(robot)
        n, m = len(robot), len(factory)
        
        distances = [[abs(r-f) for r in robot] for f in factory]
        costs = [[0] + list(accumulate(d)) for d in distances]
        
        @lru_cache(None)
        def dp(fid, pre):
            if pre == n:
                return 0
            if fid == m:
                return 0 if pre == n else math.inf
            return min(costs[fid][pre+i] - costs[fid][pre] + dp(fid+1, pre+i) for i in range(min(cnt[fid], n-pre) + 1))
        
        return dp(0, 0)

提交代码评测得到:耗时1157ms,占用内存27.4MB。

你可能感兴趣的:(leetcode笔记,周赛,318,leetcode,2460,leetcode,2461,leetcode,2462,leetcode,2463)