[LeetCode周赛复盘] 第 107 场双周赛20230624
一、本周周赛总结
- T1 哈希表模拟。
- T2 记忆化搜索。
- T3 dp。
- T4 离线+滑窗。
6898. 字符串连接删减字母
1. 题目描述
2. 思路分析
按题意模拟即可。
- 注意每个单词只能匹配一次,记得删除。
3. 代码实现
class Solution:
def maximumNumberOfStringPairs(self, words: List[str]) -> int:
p = set()
ans = 0
for w in words:
s = w[::-1]
if s in p:
ans += 1
p.remove(s)
else:
p.add(w)
return ans
6895. 构造最长的新字符串
1. 题目描述
2. 思路分析
记忆化搜索
- 令f(x,y,z,last)为用xyz个对应串,构造尾巴为last=a/b字符的最长串长度。
- 那么若last='a’则只能用x,可以从f(x-1,y,z,last=‘b’)转移而来,若转移不了,则可以只用一个x,最山是2;
- 若last=‘b’则可以用y/z,同理从对应尾字符转移而来。
3. 代码实现
class Solution:
def longestString(self, x: int, y: int, z: int) -> int:
@cache
def f(x, y, z, last):
ans = -inf
if last == 'a':
if x > 0 :
ans = max(ans,f(x-1,y,z,'b')+2,2)
elif last == 'b':
if y>0:
ans = max(ans,f(x,y-1,z,'a')+2,2)
if z>0:
ans = max(ans,f(x,y,z-1,'b')+2,2)
return ans
return max(f(x,y,z,'a'),f(x,y,z,'b'))
6898. 字符串连接删减字母
1. 题目描述
2. 思路分析
- dp。
- 由于连接顺序是固定的,影响只在之前串的首尾字符,那么可以记录每次转移完,首尾字符分别为x,y时的最小长度,然后进行分类讨论。
- 令f[i][(x,y)]为用了前i个字符串,首尾分别为xy时最小长度。
- 转移时,尝试把当前串s和前边所有串进行连接。
- 由于只有小写字符,因此状态数最多26*26,转移1000次即可。
- 实现时图方便用了defaultdict,并且可以滚动省去一维。
3. 代码实现
class Solution:
def minimizeConcatenatedLength(self, words: List[str]) -> int:
n = len(words)
f = defaultdict(lambda : inf)
a = words[0]
f[(a[0],a[-1])] = len(a)
for i in range(1,n):
a = words[i]
p = len(a)
g = defaultdict(lambda : inf)
for (s,e),v in f.items():
if a[0] == e:
g[(s,a[-1])] = min(g[(s,a[-1])], v+p-1)
else:
g[(s,a[-1])] = min(g[(s,a[-1])], v+p)
if a[-1] == s:
g[(a[0],e)] = min(g[(a[0],e)],v+p-1)
else:
g[(a[0],e)] = min(g[(a[0],e)],v+p)
f = g
return min(f.values())
6468. 统计没有收到请求的服务器数目
1. 题目描述
2. 思路分析
- 离线+滑窗。
- 读题愣了一下,logs这个变量名也有点坑人。敲成了log运行,但是白板不报错,RE 3次。
- 发现把询问离线,把事件排序,然后用cnt记录窗口内每个服务器的出现次数即可。
- 然后用n减去出现了几个服务器就是没出现的个数。
3. 代码实现
class Solution:
def countServers(self, n: int, logs: List[List[int]], x: int, queries: List[int]) -> List[int]:
m = len(queries)
ans = [0]*m
j = 0
logs.sort(key=lambda xx:xx[1])
q = deque()
cnt = Counter()
for v,i in sorted([(v,i) for i,v in enumerate(queries)] ):
while j < len(logs) and logs[j][1] <= v:
q.append(j)
cnt[logs[j][0]] += 1
j += 1
while q and logs[q[0]][1]<v-x:
p = logs[q.popleft()][0]
cnt[p] -= 1
if not cnt[p]:
del cnt[p]
ans[i] = n - len(cnt)
return ans