Sliding window
使用左右两个指针,按一定规则向右移动。注意 window 的大小并不一定是固定的。
使用 pattern
在需要找一个区间的问题中,
第一种情况:首先移动右指针使得满足要求,再移动左指针直到不满足要求,再移动右指针,持续如此,直到区间的右边界到达整体的结束点。
left = 0
init state
ret = worse case retval
for right in range(n):
update state
while state is valid:
sol = f(left, right)
if sol is better than ret:
ret = sol
left += 1
update state
return ret
第二种情况:首先移动右指针直到不满足要求,再移动左指针直到满足要求,此时记录当前状态,若更优则记录下来。持续如此,直到区间的右边界到达整体的结束点。
left = 0
init state
ret = worse case retval
for right in range(n):
update state
while state is not valid:
left += 1
update state
sol = f(left, right)
if sol is better than ret:
ret = sol
return ret
相关题目
LeetCode 76. Minimum Window Substring
第一种情况。Python 解法:
def minWindow(self, s: str, t: str) -> str:
ret = ''
# cnt: how many chars of t has been covered. just for speeding up the algo
cnt = 0
left = 0
min_size = float('inf')
chars = Counter()
target = Counter(t)
for right, sc in enumerate(s):
# for a new right pointer, update the state
chars[sc] += 1
if chars[sc] <= target[sc]:
cnt += 1
# move the left pointer right until the state becomes invalid
while cnt == len(t):
if (size := right - left + 1) < min_size:
min_size = size
ret = s[left:right + 1]
# for a new left pointer, update the state
sl = s[left]
left += 1
chars[sl] -= 1
if chars[sl] < target[sl]:
cnt -= 1
return ret
LeetCode 340. Longest Substring with At Most K Distinct Characters
第二种情况。Python 解法:
def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int:
left = 0
ret = 0
distinct = 0
chars = Counter()
for right, ch in enumerate(s):
# move the right pointer until the state is invalid
if chars[ch] == 0:
distinct += 1
chars[ch] += 1
while distinct > k and left <= right:
# move the left pointer until the state is valid
c = s[left]
left += 1
chars[c] -= 1
if chars[c] == 0:
distinct -= 1
# after the state becomes valid, record the best result
ret = max(right - left + 1, ret)
return ret