前言
接前文 滑动窗口算法 - LC76 最小覆盖子串-CSDN博客,此题也是套用滑窗模板,但是在两个细节点处稍有不同。
正文
LCR 014. 字符串的排列
给定两个字符串 s1
和 s2
,写一个函数来判断 s2
是否包含 s1
的某个变位词。
换句话说,第一个字符串的排列之一是第二个字符串的 子串 。
题解:
func checkInclusion(s2 string, s1 string) bool {
window := make(map[byte]int)
need := make(map[byte]int)
for i := 0; i < len(s2); i++ {
need[s2[i]]++
}
n := len(s1)
l, r := 0, 0
valid := 0
for r < n {
c := s1[r]
r++
if need[c] > 0 {
window[c]++
if need[c] == window[c] {
valid++
}
}
for r-l == len(s2) {
if valid == len(need) {
return true
}
d := s1[l]
l++
if need[d] > 0 {
if need[d] == window[d] {
valid--
}
window[d]--
}
}
}
return false
}
细节点:
(1)注意窗口收缩的条件发生改变,即左指针移动的条件发生改变,只要当前窗口的长度>=目标字符串的长度,即l-r >len(s2),注意不是l-r > len(need)那么就开始收缩,因为我们要找的覆盖子串是要和目标字符串长度相等的不同排列。
(2)len(need)是目标字符串里不重复元素个数,len(s2)是目标字符串长度,当r-l == len(s2)并且valid==len(need)时,说明在s1中找到了s2的不同排列的字符串,所以可以直接return true。