前言
接前文 滑动窗口算法 - 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, 0valid := 0for 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。