LeetCode 567. 字符串的排列
题目描述
思路分析
- 如果
s1
的长度大于s2
的长度,那么一定不可能包含s1
的排列,直接返回false
。- 初始化两个映射:
window
和need
。window
用于存储s1
中每个字符的频次,need
用于存储滑动窗口中字符的频次。- 使用双指针
left
和right
来遍历s2
。右指针不断扩展窗口,而左指针在窗口大小大于s1
长度时右移。- 在遍历过程中,维护
need
映射。当右指针扩展窗口时,增加相应字符的频次,当左指针右移时,减少相应字符的频次。如果字符频次减少到0,就从need
映射中删除该字符。- 如果
need
映射的长度等于window
映射的长度,并且两个映射相等,说明找到了s2
中的一个排列,返回true
。- 如果遍历完整个
s2
都没有找到满足条件的排列,返回false
。这个算法的时间复杂度是O(n),其中N是
s2
的长度。在最坏情况下,左指针和右指针都会遍历整个s2
字符串。
参考代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
func checkInclusion(s1 string, s2 string) bool {
if len(s1) > len(s2) {
return false
}
window := make(map[byte]int)
for i := 0; i < len(s1); i++ {
window[s1[i]]++
}
need := make(map[byte]int)
left, right := 0, 0
for right < len(s2) {
need[s2[right]]++
if right-left+1 > len(s1) {
c := s2[left]
need[c]--
if need[c] == 0 {
delete(need, c)
}
left++
}
if len(need) == len(window) {
if reflect.DeepEqual(need, window) {
return true
}
}
right++
}
return false
}
1
write your code here
CC BY-NC-SA 4.0
许可协议,转载请注明出处!
本博客所有文章除特别声明外,均采用