LeetCode笔记:Biweekly Contest 77

Posted Espresso Macchiato

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode笔记:Biweekly Contest 77相关的知识,希望对你有一定的参考价值。

1. 题目一

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

1. 解题思路

这一题思路还是比较直接的,就是直接统计一下所有的前缀字符,然后看一下words当中各个前缀字符出现的频次,然后相加即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def countPrefixes(self, words: List[str], s: str) -> int:
        cnt = Counter(words)
        n = len(s)
        res = 0
        for i in range(n):
            res += cnt[s[:i+1]]
        return res

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

2. 题目二

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

1. 解题思路

这一题思路上很直接,就是遍历一下每一个位置求解一下了均值之差。

而关于均值的计算,可以通过一个累积数组进行效率优化。

2. 代码实现

给出python代码实现如下:

class Solution:
    def minimumAverageDifference(self, nums: List[int]) -> int:
        s = sum(nums)
        n = len(nums)
        diff = s // n
        res = n-1
        t = 0
        for i in range(n-1):
            t += nums[i]
            tmp = abs(t // (i+1) - (s-t) // (n-i-1))
            if tmp < diff or (tmp == diff and res == n-1):
                res = i
                diff = abs(t // (i+1) - (s-t) // (n-i-1))
        return res

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

3. 题目三

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

1. 解题思路

这一题依然还是一个累积数组的思路,就是在上下左右4个方向上,分别通过守卫的位置计算出能够被覆盖到的位置,然后合并4个方向上的情况,就能够最终得到守卫覆盖情况。

2. 代码实现

给出python代码实现如下:

class Solution:
    def countUnguarded(self, m: int, n: int, guards: List[List[int]], walls: List[List[int]]) -> int:
        status = [[0 for _ in range(n)] for _ in range(m)]
        for i, j in guards:
            status[i][j] = 1
        for i, j in walls:
            status[i][j] = -1
            
        l2r = [[0 for _ in range(n)] for _ in range(m)]
        for i in range(m):
            l2r[i][0] = 0 if status[i][0] != 1 else 1
            for j in range(1, n):
                if status[i][j] == -1:
                    l2r[i][j] = 0
                else:
                    l2r[i][j] = l2r[i][j-1] + status[i][j]
                
        r2l = [[0 for _ in range(n)] for _ in range(m)]
        for i in range(m):
            r2l[i][n-1] = 0 if status[i][n-1] != 1 else 1
            for j in range(n-2, -1, -1):
                if status[i][j] == -1:
                    r2l[i][j] = 0
                else:
                    r2l[i][j] = r2l[i][j+1] + status[i][j]
                    
        t2b = [[0 for _ in range(n)] for _ in range(m)]
        for j in range(n):
            t2b[0][j] = 0 if status[0][j] != 1 else 1
            for i in range(1, m):
                if status[i][j] == -1:
                    t2b[i][j] = 0
                else:
                    t2b[i][j] = t2b[i-1][j] + status[i][j]
                    
        b2t = [[0 for _ in range(n)] for _ in range(m)]
        for j in range(n):
            b2t[m-1][j] = 0 if status[m-1][j] != 1 else 1
            for i in range(m-2, -1, -1):
                if status[i][j] == -1:
                    b2t[i][j] = 0
                else:
                    b2t[i][j] = b2t[i+1][j] + status[i][j]
        
        res = [(i, j) for i in range(m) for j in range(n) if status[i][j] != -1 and l2r[i][j] + r2l[i][j] + t2b[i][j] + b2t[i][j] == 0]
        return len(res)

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

4. 题目四

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

1. 解题思路

这一题我的思路是分别计算火蔓延到每个位置所需要的时间和人跑到每一个位置上所需要的最短时间。

如果火蔓延截断了必经路线的时间短于人跑到这个位置的最短时间,那么人就无法逃离,反之,如果大于,那么这个时间差就是针对这个路线能够等待的最长时间。

唯一需要注意的是,这里有一个比较特殊的位置,就是安全屋的位置,只有这个地方可以使得等待时间+1,因此只有这个位置可以允许人和火在同一时间到达。

2. 代码实现

给出python代码实现如下:

class Solution:
    def maximumMinutes(self, grid: List[List[int]]) -> int:
        n, m = len(grid), len(grid[0])
        times = [[0 for _ in range(m)] for _ in range(n)]
        seen = (0, 0)
        q = [(0, 0, 0)]
        while q:
            t, i, j = q.pop(0)
            times[i][j] = t
            if i == n-1 and j == m-1:
                break
            if (i-1, j) not in seen and i-1 >= 0 and grid[i-1][j] == 0:
                q.append((t+1, i-1, j))
                seen.add((i-1, j))
            if (i+1, j) not in seen and i+1 < n and grid[i+1][j] == 0:
                q.append((t+1, i+1, j))
                seen.add((i+1, j))
            if (i, j-1) not in seen and j-1 >= 0 and grid[i][j-1] == 0:
                q.append((t+1, i, j-1))
                seen.add((i, j-1))
            if (i, j+1) not in seen and j+1 < m and grid[i][j+1] == 0:
                q.append((t+1, i, j+1))
                seen.add((i, j+1))
        if times[-1][-1] == 0:
            return -1
        
        cnt = defaultdict(int)
        for i in range(n):
            for j in range(m):
                if times[i][j] != 0:
                    cnt[times[i][j]] += 1
        cnt[times[i][j]] = 1

        fires = [[0 for _ in range(m)] for _ in range(n)]
        q = [(0, i, j) for i in range(n) for j in range(m) if grid[i][j] == 1]
        seen = (i, j) for i in range(n) for j in range(m) if grid[i][j] == 1
        res = 1000000000
        while q:
            t, i, j = q.pop(0)
            fires[i][j] = t
            if times[i][j] != 0 and times[i][j] <= times[-1][-1]:
                if times[i][j] != times[-1][-1] or (i == n-1 or j == m-1):
                    cnt[times[i][j]] -= 1
                    if cnt[times[i][j]] == 0:
                        if i == n-1 and j == m-1:
                            if t - times[i][j] >= 0:
                                res = min(res, t - times[i][j])
                            else:
                                return -1
                        else:   
                            if t - times[i][j] - 1 >= 0:
                                res = min(res, t - times[i][j] - 1)
                            else:
                                return -1
            if (i-1, j) not in seen and i-1 >= 0 and grid[i-1][j] == 0:
                q.append((t+1, i-1, j))
                seen.add((i-1, j))
            if (i+1, j) not in seen and i+1 < n and grid[i+1][j] == 0:
                q.append((t+1, i+1, j))
                seen.add((i+1, j))
            if (i, j-1) not in seen and j-1 >= 0 and grid[i][j-1] == 0:
                q.append((t+1, i, j-1))
                seen.add((i, j-1))
            if (i, j+1) not in seen and j+1 < m and grid[i][j+1] == 0:
                q.append((t+1, i, j+1))
                seen.add((i, j+1))
        return res

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

以上是关于LeetCode笔记:Biweekly Contest 77的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode笔记:Biweekly Contest 79

LeetCode笔记:Biweekly Contest 93

LeetCode笔记:Biweekly Contest 89

LeetCode笔记:Biweekly Contest 69

LeetCode笔记:Biweekly Contest 74

LeetCode笔记:Biweekly Contest 96