# A. Minimum Recolors to Get K Consecutive Black Blocks (opens new window)
Slidwng window of fixed length.
DETAILS
def minimumRecolors(self, A: str, k: int) -> int:
c = collections.Counter(A[:k])
ans = c.get('W', 0)
for i in range(k, len(A)):
c[A[i]] += 1
c[A[i - k]] -= 1
ans = min(ans, c.get('W', 0))
return ans
# B. Time Needed to Rearrange a Binary String (opens new window)
Brute Force.
DETAILS
def secondsToRemoveOccurrences(self, s: str) -> int:
A, d = list(map(int, list(s))), 0
for _ in range(1000):
cnt, prev = 0, 0
for i in range(len(s) - 1, 0, -1):
if A[i] == 1 and A[i - 1] == 0 and prev == 0:
cnt += 1
A[i], A[i - 1] = A[i - 1], A[i]
prev = 1
else:
prev = 0
if cnt == 0:
return d
d += 1
return -1
# C. Shifting Letters II (opens new window)
Prefix sum.
DETAILS
def shiftingLetters(self, S: str, A: List[List[int]]) -> str:
n = len(S)
P = [0] * (n + 1)
for l, r, a in A:
if a == 1:
P[l] += 1
P[r + 1] -= 1
else:
P[l] -= 1
P[r + 1] += 1
cur = 0
ans = ""
for i, s in enumerate(S):
cur += P[i]
ans += chr(ord('a') + (ord(s) - ord('a') + cur) % 26)
return ans
# 2382. Maximum Segment Sum After Removals (opens new window)
DSU on the reversed removal array. (or Max-stack on removal array)
DETAILS
class UF:
def __init__(self, n):
self.root = list(range(n))
self.rk = [0] * n
def find(self, x):
if self.root[x] != x:
self.root[x] = self.find(self.root[x])
return self.root[x]
def union(self, x, y):
rx, ry = self.find(x), self.find(y)
if rx != ry:
if self.rk[rx] > self.rk[ry]:
rx, ry = ry, rx
self.root[rx] = ry
self.rk[ry] += self.rk[rx]
def getSize(self, x):
rx = self.find(x)
return self.rk[rx]
class Solution:
def maximumSegmentSum(self, A: List[int], Q: List[int]) -> List[int]:
n = len(A)
uf = UF(n)
ans = [0]
maxs = 0
for q in Q[::-1]:
uf.rk[q] = A[q]
if q > 0 and uf.rk[q - 1]:
uf.union(q, q - 1)
if q < n - 1 and uf.rk[q + 1]:
uf.union(q, q + 1)
maxs = max(maxs, uf.getSize(q))
ans.append(maxs)
return ans[::-1][1:]