这里记录一下使用python写的滑动窗口经典题的题解,欢迎大家指正和交流。
含有不同的k个字符的最长子串
包含k个字符以上左边界右移
有边界右移,如果出现新的字符则count++
如果count <= k, 更新res
def longestSubstringKDistinctLetter(nums, k):
bitmap = dict()
left, right = 0, 0
count = 0
res = 0
for i in range(256):
bitmap[chr(i)] = 0
while(right < len(nums)):
if(count > k):
if(bitmap[nums[left]] - 1 == 0):
count -= 1
bitmap[nums[left]] -= 1
left += 1
continue
# 为什么要加continue,因为
# 进入这个if的就是因为此时count>k,left必须左移到count = k,continue的意义是
# 跳过后面的right的右移
if(bitmap[nums[right]] == 0):
count += 1
bitmap[nums[right]] = bitmap[nums[right]] + 1
if(count <= k): res = max(res, right - left + 1)
right += 1
return res
end后移,增加sum,如果sum>value
while (sum - nums[start] >= k): start后移,更新lenn,返回2
如果sum - nums[start] < k: 返回1
def smallestSubarray(nums, value):
start, end = 0, 0
if(len(nums) == 0): return 0
lenn = float('inf')
summ = 0
while(end < len(nums)):
summ += nums[end]
while(summ > value):
if(summ - nums[start] > value):
start += 1
summ = summ - nums[start]
lenn = min(lenn, end - start + 1)
end += 1
return lenn
def maxSizeOfSubarr(arr, k):
if(len(arr)==0): return 0
sum1=0
res=0
hasht = dict()
hasht[0] = 0
for i in range(0, len(arr)):
sum1 += arr[i]
if((sum1 - k) in hasht):
res = max(res, i + 1 - hasht[sum1-k])
if(sum1 not in hasht):
hasht[sum1] = i + 1
return res
从任意位置开始,如果最多只能收集两种水果,
那么最多可以收集多少水果,我看着不方便,我理解为最多可以收集到几颗果树
感觉和340是一样的
具体思路参考340
def maximumFruits(nums, k=2):
bitmap = dict()
left, right = 0, 0
count = 0
res = 0
for i in range(256):
bitmap[i] = 0
while(right < len(nums)):
if(count > k):
if(bitmap[nums[left]] - 1 == 0):
count -= 1
bitmap[nums[left]] -= 1
left += 1
continue
# 为什么要加continue,因为
# 进入这个if的就是因为此时count>k,left必须左移到count = k,continue的意义是
# 跳过后面的right的右移
if(bitmap[nums[right]] == 0):
count += 1
bitmap[nums[right]] = bitmap[nums[right]] + 1
if(count <= k): res = max(res, right - left + 1)
right += 1
return res
求最长无重复子串, 给出一个字符串, 从所有子串中, 找出最长, 且没有重复字母的子串的长度.
def findLongestSubstr(s):
right, left, res = 0, 0, 0
length = len(s)
sett = set()
while(right < length):
if(s[right] not in sett):
res = max(res, right - left + 1)
sett.add(s[right])
right += 1
else:
while(s[left] != s[right]):
left += 1
sett.remove(s[left])
left += 1
return res
替换后最长重复子串
双指针窗口滑动法。使用两个指针分别作为窗口的left、right,
不断右移动right指针(扩大窗口),
将窗口中的字符数作为一个中间结果(替换后的最长重复字符),
当窗口大小 - 窗口中出现次数最多的字符数即是需要替换的字母数。
如果需要替换的字母数超过了k,则说明需要缩小窗口(右移left)。
def maxLengthRepeatedSubstr(strr, k):
right, left = 0, 0
lenn = len(strr)
letter_map = dict()
count, res = 0, 0
for i in range(26):
letter_map[chr(ord('A') + i)] = 0
while(right < lenn):
letter_map[strr[right]] += 1
count = max(count, letter_map[strr[right]])
while(right - left + 1 - count > k):
letter_map[strr[left]] -= 1
left += 1
res = max(res, right - left + 1)
right += 1
return res
大家共勉~