第 85 场双周赛 总结
得到 K 个黑块的最少涂色次数
刚开始做没有反应过来,后来想了想就是滚动大小为k的窗口,
统计窗口中白色方块的最小值即可
class Solution:
def minimumRecolors(self, blocks: str, k: int) -> int:
temp=0
l,r=0,k-1
blocks=list(blocks)
for i in range(k):
if blocks[i]=='W':
temp+=1
res=temp
for i in range(len(blocks)-k):
if blocks[l]=='W':
temp-=1
l+=1
r+=1
if blocks[r]=='W':
temp+=1
res=min(res,temp)
return res
二进制字符串重新安排顺序需要的时间
先用暴力train了一发,结果过了,看的出来数据强度很小
class Solution:
def secondsToRemoveOccurrences(self, s: str) -> int:
res=0
n= len(s)
while 1:
ss=s.replace("01", "10")
if ss==s:
break
s=ss
res+=1
return res
之后看讨论区,这个题目就是每次将1往前移动,最后将所有1都移动到0的前面
如果1的前面全是0的话,只要移动0个数的次数即可
如果1遇到前面相邻1的情况,移动次数至少是前一个1移动次数+1
class Solution:
def secondsToRemoveOccurrences(self, s: str) -> int:
res = pre = 0
for ss in s:
if ss == '0':
pre += 1
elif pre:
res = max(res + 1, pre)
return res
字母移位 II
该问题涉及到区间修改和单点查询,典型的差分数组的运用
class Solution:
def shiftingLetters(self, s: str, shifts: List[List[int]]) -> str:
diff = [0] * (len(s) + 1)
c2i = {code: index for index, code in enumerate(ascii_lowercase)}
for start, end, dir in shifts:
if dir:
diff[start] += 1
diff[end + 1]-= 1
else:
diff[start] += -1
diff[end + 1]-= -1
run=0
res=[]
for code, pos in zip(s, diff):
run+=pos
res.append(ascii_lowercase[(c2i[code] + run) % 26])
return ''.join(res)
删除操作后的最大子段和
相比一个个删除计算,从后向前一个个添加计算显然更为简单,而链接两个连通块可以采用并查集的方式,本题里采用向后联通的方式
class Solution:
def maximumSegmentSum(self, nums: List[int], removeQueries: List[int]) -> List[int]:
n = len(nums)
fa = list(range(n + 1))
sum = [0] * (n + 1)
def find(x: int) -> int:
return fa[x] if fa[x]==x else find(fa[x])
ans = [0]
for i in range(n - 1, 0, -1):
now = removeQueries[i]
to = find(now + 1)
fa[now] = to
sum[to] += sum[now] + nums[now]
ans.append(max(ans[-1], sum[to]))
return ans[::-1]
总结
算是回顾了一下差分数组和并查集的用法吧