LeetCode笔记:Weekly Contest 334

1. 题目一

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

1. 解题思路

这一题用一个累积数组就能够快速求解。

2. 代码实现

给出python代码实现如下:

class Solution:
    def leftRigthDifference(self, nums: List[int]) -> List[int]:
        lsum = list(accumulate(nums))
        s = lsum[-1]
        res = [abs(x - (s-x+nums[i])) for i, x in enumerate(lsum)]
        return res

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

2. 题目二

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

1. 解题思路

这一题就是不断地取前i个字符组成的数对m进行求模即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def divisibilityArray(self, word: str, m: int) -> List[int]:
        res = []
        s = 0
        for ch in word:
            s = (s * 10 + int(ch)) % m
            if s == 0:
                res.append(1)
            else:
                res.append(0)
        return res

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

3. 题目三

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

1. 解题思路

这一题有一点丢脸,本质上这道题就是排序之后给出一个最大的变换构造,但是居然没构造出来,最后是看了答案之后才想到的构造,简直丢脸到家了。

显然,这道题假设数组长度为n,那么最多可以pick的组数至多为 n / 2 n/2 n/2,因此,我们只要令i都来自于前半组,j都来自于后半组,然后greedy地选出对应可能的pair即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def maxNumOfMarkedIndices(self, nums: List[int]) -> int:
        nums = sorted(nums)
        n = len(nums)
        i, j = (n-1) // 2, n-1
        res = 0
        while i >= 0 and j > (n-1) // 2:
            if nums[i]*2 > nums[j]:
                i-= 1
                continue
            res += 2
            i -= 1
            j -= 1
        return res   

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

4. 题目四

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

1. 解题思路

这一题思路上倒是不复杂,就是一个广度优先遍历,我们用时间t来作为广度判断,来确定遍历顺序,然后扩展直到终点即可。

这里,我们只需要注意以下几个点:

  1. 如果第一个点周围的位置都无法访问,那么会导致游客无法行动,只能返回-1,反之,游客总可以在两点间游荡来等到下一个点可以访问,因此绝不会出现-1的情况;
  2. 如果某一个点当前无法访问,那么访问该点的时间就是 m i n ( 2 k + t , t o p e n ) min(2k+t, t_{open}) min(2k+t,topen);
  3. 注意剪枝来优化时间复杂度。

2. 代码实现

给出python代码实现如下:

class Solution:
    def minimumTime(self, grid: List[List[int]]) -> int:
        if grid[0][1] > 1 and grid[1][0] > 1:
            return -1
        
        n, m = len(grid), len(grid[0])
        t_reach = {(0, 0): 0}
        q = [(grid[0][0], 0, 0)]
        while q != []:
            t, x, y = heapq.heappop(q)
            if t > t_reach.get((x, y), math.inf):
                continue
            if (x,y) == (n-1, m-1):
                return t
            if x-1 >= 0:
                nxt = t+1 + 2 * max(0, (grid[x-1][y]-t)//2)
                if t_reach.get((x-1, y), math.inf) > nxt:
                    heapq.heappush(q, (nxt, x-1, y))
                    t_reach[(x-1, y)] = nxt
            if x+1 < n:
                nxt = t+1 + 2 * max(0, (grid[x+1][y]-t)//2)
                if t_reach.get((x+1, y), math.inf) > nxt:
                    heapq.heappush(q, (nxt, x+1, y))
                    t_reach[(x+1, y)] = nxt
            if y-1 >= 0:
                nxt = t+1 + 2 * max(0, (grid[x][y-1]-t)//2)
                if t_reach.get((x, y-1), math.inf) > nxt:
                    heapq.heappush(q, (nxt, x, y-1))
                    t_reach[(x, y-1)] = nxt
            if y+1 < m:
                nxt = t+1 + 2 * max(0, (grid[x][y+1]-t)//2)
                if t_reach.get((x, y+1), math.inf) > nxt:
                    heapq.heappush(q, (nxt, x, y+1))
                    t_reach[(x, y+1)] = nxt
        return -1

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值