文章目录
- 滑动窗口长度固定
- 28.实现strStr()
- 567.字符串的排列
- 滑动窗口长度不固定
- 209.长度最小的子数组
- 3.无重复字符的最长子串
- 485. 最大连续1的个数
- 487. 最大连续1的个数2
- 1004.最大连续1的个数3
滑动窗口长度固定
滑动窗口模板:
min_len = float('inf')
max_len = float('-inf')
start = 0
for end in range(len(滑动窗口)-1, len(字符串/列表)):
while() or if()
if max_len == float('-inf')(or if min_len == float('inf')):
return 0
else:
return max_len(or return min_len)
28.实现strStr()
题目:给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1
- 窗口长度固定,为len(needle)
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
start = 0
for end in range(len(needle)-1, len(haystack)):
if haystack[start:end-start+1] == needle:
return start
start += 1
return -1
567.字符串的排列
题目:给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列(不考虑次序)。如果是,返回 true ;否则,返回 false 。
- 只求s2中是否含有s1的排列,即不考虑次序,‘ab’==‘ba’。采用字典很合适
- 窗口长度固定,为len(s1)
class Solution:
def checkInclusion(self, s1: str, s2: str) -> bool:
start = 0
from collections import Counter
adict = Counter(s1)
for end in range(len(s1)-1, len(s2)):
if Counter(s2[start:end+1]) == adict:
return True
else:
start += 1
return False
滑动窗口长度不固定
209.长度最小的子数组
题目:给定一个数组nums、一个正整数 target 。找出该数组中满足其和 ≥ target 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的子数组,返回 0 。
- 窗口长度不固定
- 最小,min_len上场
- 和>target 且连续子数组,假设数组为[1,2,2,3,3],target=7。那么在变动start,end不变的前提下,子数组[1,2,2,3]和子数组[2,2,3]是满足条件的。因此需要用while循环来判断start到end中的每个子数组是否满足和>target 这个条件。
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
min_len = float('inf')
start = 0
cur_sum = 0 // 记录以start开头,end为末尾的子数组的和
for end in range(len(nums)):
cur_sum += nums[end]
while start <= end and cur_sum >= target: // 子数组循环里需要做的事情
min_len = min(min_len, end-start+1) // 当条件满足时,更新min_len的长度
cur_sum -= nums[start] // 看看数组里是否还有其他的子数组符合循环条件
start += 1 // 更新start的值,方便重新更新min_len
if min_len == float('inf'):
return 0
else:
return min_len
3.无重复字符的最长子串
题目:给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串的长度。 s = abcabcbb
- 窗口长度不固定
- 最长,max_len上场
- 循环条件是无重复字符(当起始位置为start,第一个无重复子串的结束位置为end,那么【start+1:end】等子串肯定是无重复,我们只需要依次增大end来获取开头在【start:end】间的所有无重复子串)
- 什么时候移动start,对于字符串abca,当出现重复字符a时,我们需要移动start来判断bc中是否含有字符a
- 什么时候更新max_len,// while循环出来后可以保证列表中无重复的字符,此时可以更新max_len
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
max_len = float('-inf')
start = 0
l = []
for end in range(len(s)):
while s[end] in l:
s.remove(s[start])
start += 1
max_len = max(max_len, end - start + 1)
l.append(s[end])
if max_len == float('-inf'):
return 0
else:
return max_len
485. 最大连续1的个数
题目:给定一个二进制数组 nums , 计算其中最大连续 1 的个数。
class Solution:
def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
start = 0
count = 0
max_len = float('-inf')
for end in range(len(nums)):
if nums[end] == 1:
count += 1
while count < end - start + 1:
if nums[start] == 1:
count -= 1
start += 1
max_len = max(max_len, end - start + 1)
if max_len == float('-inf'):
return 0
else:
return max_len
487. 最大连续1的个数2
题目:给定一个二进制数组,你可以最多将 1 个 0 翻转为 1,找出其中最大连续 1 的个数。
class Solution:
def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
start = 0
count = 0
max_len = float('-inf')
for end in range(len(nums)):
if nums[end] == 1:
count += 1
while count + 1 < end - start + 1:
if nums[start] == 1:
count -= 1
start += 1
max_len = max(max_len, end - start + 1)
if max_len == float('-inf'):
return 0
else:
return max_len
1004.最大连续1的个数3
题目:给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回数组中连续 1 的最大个数 。
class Solution:
def longestOnes(self, nums: List[int], k: int) -> int:
start = 0
count = 0
max_len = float('-inf')
for end in range(len(nums)):
if nums[end] == 1:
count += 1
while count + k < end - start + 1:
if nums[start] == 1:
count -= 1
start += 1
max_len = max(max_len, end - start + 1)
if max_len == float('-inf'):
return 0
else:
return max_len
485,487,1004都可以套用滑动窗口的同一个模板。
如果窗口的长度比count+k的极限长度还要大,说明这个窗口长度是有问题的,就要想办法更新一些窗口的附属值。窗口满足要求就可以计算长度了。