链接:
https://leetcode.cn/problems/permutation-in-string/
给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。
换句话说,s1 的排列之一是 s2 的 子串 。
示例 1:
输入:s1 = “ab” s2 = “eidbaooo”
输出:true
解释:s2 包含 s1 的排列之一 (“ba”).
示例 2:
输入:s1= “ab” s2 = “eidboaoo”
输出:false
提示:
1 <= s1.length, s2.length <= 104
s1 和 s2 仅包含小写字母
使用滑动窗口,labuladong的python源码如下,仅对代码进行解释:
# 判断 s 中是否存在 t 的排列
def checkInclusion(t: str, s: str) -> bool:
from collections import defaultdict
need, window = defaultdict(int), defaultdict(int) #need和window记录目标和窗口的字符频次
for c in t: #need初始化
need[c] += 1
left, right = 0, 0
valid = 0 #valid记录多少个字符的频次是一致的,当valid == len(need),说明全匹配到了
while right < len(s):
c = s[right] #进入窗口的字符
right += 1 #窗口向右移动
# 进行窗口内数据的一系列更新
if c in need: #为什么判断c是否在need中?因为如果不在need中的,统计没意义
window[c] += 1
if window[c] == need[c]:
valid += 1
# 判断左侧窗口是否要收缩
while right - left >= len(t): #这里改成if也可,每次都固定窗口大小,注意,这里的>=不可以改成!=,
#因为在刚开始,right-left是<len(t)的(<也是!=),这个时候left是不动的;按理说可以改成==,还没验证
# 在这里判断是否找到了合法的子串
if valid == len(need): #窗口是慢慢变大到定长的,不可能出现大于len(need)的情况,所以可以直接判断
return True
d = s[left]
left += 1
# 进行窗口内数据的一系列更新
if d in need:
if window[d] == need[d]:
valid -= 1
window[d] -= 1
# 未找到符合条件的子串
return False