[LeetCode周赛复盘] 第 300 场周赛20220703
一、本周周赛总结
- 过辣!
- 第三题dp比第四题难多了。
- 第六次周赛,第二次ak,今天的题确实都不难,两道模拟,两道dp。
- T3卡了一会,觉得麻烦就去看T4了,DP还是得多练!
- T4忘记取模wa了一次,下次遇到取模题先把return ans%mod写在最后一行!
二、 [Easy] 6108. 解密消息
链接: 6108. 解密消息
1. 题目描述
2. 思路分析
定级Easy。
用一个字典记录第一次出现的位置,替换即可。
3. 代码实现
class Solution:
def decodeMessage(self, key: str, message: str) -> str:
first = {}
cnt = 0
for i,c in enumerate(key):
if c != ' ' and c not in first:
first[c] = cnt
cnt += 1
ans = []
for c in message:
if c == ' ':
ans.append(c)
else:
ans.append(chr(first[c]+ord('a')))
return ''.join(ans)
三、[Medium] 6111. 螺旋矩阵 IV
链接: 6111. 螺旋矩阵 IV
1. 题目描述
2. 思路分析
定级Medium。
- 定好四个方向,模拟即可。
- 初始化都是-1,遇到越界或者填过的数就转头。
3. 代码实现
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def spiralMatrix(self, m: int, n: int, head: Optional[ListNode]) -> List[List[int]]:
ans = [[-1]*n for _ in range(m)]
def in_bound(x,y):
return 0<=x<m and 0<=y<n and ans[x][y] == -1
x,y=0,0
dir = 3 # 0123 上下左右
while head:
ans[x][y] = head.val
if dir == 3:
x1,y1 = x,y+1
if not in_bound(x1,y1):
x1,y1 = x+1,y
dir = 1
elif dir == 1:
x1,y1 = x+1,y
if not in_bound(x1,y1):
x1,y1 = x,y-1
dir = 2
elif dir == 2:
x1,y1 = x,y-1
if not in_bound(x1,y1):
x1,y1 = x-1,y
dir = 0
elif dir == 0:
x1,y1 = x-1,y
if not in_bound(x1,y1):
x1,y1 = x,y+1
dir = 3
x,y = x1,y1
head = head.next
return ans
四、[Medium] 6109. 知道秘密的人数
链接: 6109. 知道秘密的人数
1. 题目描述
2. 思路分析
定级Medium。
- dp。
- 令dp[i][j] 是第i天,知道秘密且记忆还剩j天的人。
- dp[0][forget-1] =1 是A
- 第二天,A记忆减少,去到dp[1][forget-2]
- 状态转移:
- 0到forget-2:dp[i][j] = dp[i-1][j+1]
- forget-1:昨天记忆不为0的人,且超过delay
3. 代码实现
class Solution:
def peopleAwareOfSecret(self, n: int, delay: int, forget: int) -> int:
MOD = 10**9 + 7
dp = [[0]* (forget) for _ in range(n)]
dp[0][forget-1] = 1
for i in range(1,n):
for j in range(1,forget-delay+1):
dp[i][forget-1] += dp[i-1][j]
for j in range(forget-1):
dp[i][j] = dp[i-1][j+1]
# print (dp)
return sum(dp[n-1])%MOD
五、[Hard] 6110. 网格图中递增路径的数目
1. 题目描述
2. 思路分析
定级Hard。
这题比第三题简单,排序后dp即可。
- 令dp[i][j]为以i,j这个位置为终点的路径数。
- 显然dp[i][j]只能从四周比它小的数转移而来。
- 计算每个格子需要先计算四周比它小的格子。
- 因此我们需要按数值给格子排序,然后按顺序从小到大dp。
- 最后sum所有即可。
- 因为忘记取模wa了一发,难受。
- 下次遇到取模题先把return ans%mod写在最后一行!
3. 代码实现
class Solution:
def countPaths(self, grid: List[List[int]]) -> int:
MOD = 10**9+7
m,n = len(grid),len(grid[0])
dp = [[1]*n for _ in range(m)]
def in_bound(x,y):
return 0<=x<m and 0<=y<n
dirs = [
(0,1),
(0,-1),
(1,0),
(-1,0),
]
tmp = []
for i in range(m):
for j in range(n):
tmp.append((grid[i][j],i,j))
tmp.sort()
for v,x,y in tmp:
for dx,dy in dirs:
x1,y1 = x+dx,y+dy
if in_bound(x1,y1) and grid[x1][y1] < v:
dp[x][y] += dp[x1][y1]
return sum(sum(row) for row in dp)%MOD