一、滑动窗口问题基础
滑动窗口通用框架:
class Solution:
def problemName(self, s: str) -> int:
# Step 1: 定义需要维护的变量们 (对于滑动窗口类题目,这些变量通常是最小长度,最大长度,或者哈希表)
x, y = ..., ...
# Step 2: 定义窗口的首尾端 (start, end), 然后滑动窗口
start = 0
for end in range(len(s)):
# Step 3: 更新需要维护的变量, 有的变量需要一个if语句来维护 (比如最大最小长度)
x = new_x
if condition:
y = new_y
'''
------------- 下面是两种情况,读者请根据题意二选1 -------------
'''
# Step 4 - 情况1
# 如果题目的窗口长度固定:用一个if语句判断一下当前窗口长度是否达到了限定长度
# 如果达到了,窗口左指针前移一个单位,从而保证下一次右指针右移时,窗口长度保持不变,
# 左指针移动之前, 先更新Step 1定义的(部分或所有)维护变量
if 窗口长度达到了限定长度:
# 更新 (部分或所有) 维护变量
# 窗口左指针前移一个单位保证下一次右指针右移时窗口长度保持不变
# Step 4 - 情况2
# 如果题目的窗口长度可变: 这个时候一般涉及到窗口是否合法的问题
# 如果当前窗口不合法时, 用一个while去不断移动窗口左指针, 从而剔除非法元素直到窗口再次合法
# 在左指针移动之前更新Step 1定义的(部分或所有)维护变量
while 不合法:
# 更新 (部分或所有) 维护变量
# 不断移动窗口左指针直到窗口再次合法
# Step 5: 返回答案
return ...
二、3. 无重复字符的最长子串
1 题目
2 解题思路
(1)遍历,用dict哈希保存没有重复的字符,如果有字符重复,则移动窗口左边界
(2)但是,左窗口边界怎么移动了,当前的inxdex和dict中重复的值的index,取两者较右者
3 code
class Solution(object):
def lengthOfLongestSubstring(self, s):
dict={}
res=0
i=-1
for j in range(len(s)):
# 窗口边界核心移动逻辑
if s[j] in dict:
i=max(dict[s[j]],i)
# dict哈希记录
dict[s[j]]=j
# 业务逻辑
res=max(res,j-i)
return res
三、438. 找到字符串中所有字母异位词
1 题目
2 解题思路
(1)统计p的字母频率
(2)比较p与s的子字母串
3 code
from collections import Counter
class Solution:
def isis(self,s,p_counter):
return Counter(s)==p_counter
def findAnagrams(self, s: str, p: str) -> List[int]:
# 统计p的字母频率
p_counter=Counter(p)
lst=[]
for i in range(len(s)-len(p)+1):
# s中的子字母串
substr=s[i:i+len(p)]
# p和s子串
if self.isis(substr,p_counter):
lst.append(i)
return lst