LeetCode笔记:Weekly Contest 350

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

1. 题目一

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

  • 2739. Total Distance Traveled

1. 解题思路

这一题我的做法相对比较暴力,原则上应该可以直接给出公式解的,不过我偷了个懒,单纯模拟了一下整个过程,也能够获得答案。

2. 代码实现

给出python代码实现如下:

class Solution:
    def distanceTraveled(self, mainTank: int, additionalTank: int) -> int:
        fuel = 0
        while mainTank >= 5 and additionalTank > 0:
            mainTank -= 4
            fuel += 5
            additionalTank -= 1
        fuel += mainTank
        return 10 * fuel

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

2. 题目二

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

  • 2740. Find the Value of the Partition

1. 解题思路

这一题其实就是一个脑筋急转弯的题目,其实问的就是数列中任意两元素的最小差值,想明白这一点的话其实基本就是秒答了……

2. 代码实现

给出python代码实现如下:

class Solution:
    def findValueOfPartition(self, nums: List[int]) -> int:
        nums = sorted(nums)
        n = len(nums)
        return min(nums[i+1] - nums[i] for i in range(n-1))

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

3. 题目三

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

  • 2741. Special Permutations

1. 解题思路

这一题就是一个动态规划的题目,我们首先考察一下可以相邻的元素的可能性,然后动态规划遍历一下所有的排布可能性即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def specialPerm(self, nums: List[int]) -> int:
        MOD = 10**9 + 7
        
        n = len(nums)
        allowlist = defaultdict(list)
        for i in range(n-1):
            for j in range(i+1, n):
                if nums[i] % nums[j] == 0 or nums[j] % nums[i] == 0:
                    allowlist[i].append(j)
                    allowlist[j].append(i)
               
        @lru_cache(None)
        def dp(idx, status):
            if status == 2**n-1:
                return 1
            res = 0
            for i in allowlist[idx]:
                if status & (1 << i) == 0:
                    res += dp(i, status | 1 << i)
            return res % MOD
        
        return sum(dp(i, 1 << i) for i in range(n)) % MOD

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

4. 题目四

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

  • 2742. Painting the Walls

1. 解题思路

这一题我的思路是深度优先遍历加剪枝。

我们分别考察每一个位置上选择付费工人与否的情况,但是显然这样会带来最多 2 500 2^{500} 2500的计算量,显然是不可行的,但是我们可以通过剪枝令其可以被接受:

  1. 原则上,我们肯定是优先选取单位时间费用最低的墙交给付费工人去刷,而令单位时间消耗费用最多的墙让免费工人去刷;
  2. 如果某一时刻,后续刷完剩余未刷的墙所需的费用已经多余当前某一个遍历的路径当中耗费的费用,那么也就没有必要继续这个方案进行后续的检索了。

其中,前者,我们可以通过排序进行完成,而后者,我们可以通过另一个动态规划进行完成。

2. 代码实现

给出python代码实现如下:

class Solution:
    def paintWalls(self, cost: List[int], time: List[int]) -> int:
        n = len(cost)
        s = [(c, t) for c, t in zip(cost, time)]
        s = sorted(s, key=lambda x: (x[0] / min(n, x[1]), -min(n, x[1]), x[0]))
        
        res = sum(cost)
        
        @lru_cache(None)
        def dp(idx, to_paint):
            if to_paint <= 0:
                return 0
            if idx >= n:
                return math.inf
            return min(s[idx][0] + dp(idx+1, to_paint-1-s[idx][1]), dp(idx+1, to_paint))
        
        def dfs(idx, painted, cost):
            nonlocal res
            if painted >= n:
                res = min(res, cost)
            if idx >= n:
                return
            if cost + dp(idx, n-painted) >= res:
                return
            
            dfs(idx+1, painted + 1 + s[idx][1], cost + s[idx][0])
            dfs(idx+1, painted, cost)
            return
        
        dfs(0, 0, 0)
        return res

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

你可能感兴趣的:(leetcode笔记,力扣周赛,350,leetcode,2739,leetcode,2740,leetcode,2741,leetcode,2742)