40
40
41
41
<!-- 这里可写通用的实现逻辑 -->
42
42
43
+ ** 方法一:滑动窗口**
44
+
45
+ 我们观察发现,题目实际上等价于判断字符串 $s2$ 中是否存在窗口大小为 $n$,且窗口内的字符及其个数与字符串 $s1$ 相同的子串。
46
+
47
+ 因此,我们先用哈希表或数组 $cnt1$ 统计字符串 $s1$ 中每个字符出现的次数,然后遍历字符串 $s2$,维护一个窗口大小为 $n$ 的滑动窗口,用哈希表或数组 $cnt2$ 统计窗口内每个字符出现的次数,当 $cnt1 = cnt2$ 时,说明窗口内的字符及其个数与字符串 $s1$ 相同,返回 ` true ` 即可。
48
+
49
+ 否则,遍历结束后,返回 ` false ` 。
50
+
51
+ 时间复杂度 $(n + m \times C)$,空间复杂度 $O(C)$。其中 $n$ 和 $m$ 分别为字符串 $s1$ 和 $s2$ 的长度;而 $C$ 为字符集的大小,本题中 $C=26$。
52
+
53
+ ** 方法二:滑动窗口优化**
54
+
55
+ 在方法一中,我们每次加入和移除一个字符时,都需要比较两个哈希表或数组,时间复杂度较高。我们可以维护一个变量 $diff$,表示两个大小为 $n$ 的字符串中,有多少种字符出现的个数不同。当 $diff=0$ 时,说明两个字符串中的字符个数相同。
56
+
57
+ 时间复杂度 $O(n + m)$,空间复杂度 $O(C)$。其中 $n$ 和 $m$ 分别为字符串 $s1$ 和 $s2$ 的长度;而 $C$ 为字符集的大小,本题中 $C=26$。
58
+
43
59
<!-- tabs:start -->
44
60
45
61
### ** Python3**
49
65
``` python
50
66
class Solution :
51
67
def checkInclusion (self , s1 : str , s2 : str ) -> bool :
52
- need, window = {}, {}
53
- validate, left, right = 0 , 0 , 0
54
- for c in s1:
55
- window[c] = 0
56
- if c in need:
57
- need[c] += 1
58
- else :
59
- need[c] = 1
60
-
61
- for right in range (len (s2)):
62
- c = s2[right]
63
- if c in need:
64
- window[c] += 1
65
- if window[c] == need[c]:
66
- validate += 1
67
- while right - left + 1 >= len (s1):
68
- if validate == len (need):
69
- return True
70
- d = s2[left]
71
- left += 1
72
- if d in need:
73
- if window[d] == need[d]:
74
- validate -= 1
75
- window[d] -= 1
68
+ n = len (s1)
69
+ cnt1 = Counter(s1)
70
+ cnt2 = Counter(s2[:n])
71
+ if cnt1 == cnt2:
72
+ return True
73
+ for i in range (n, len (s2)):
74
+ cnt2[s2[i]] += 1
75
+ cnt2[s2[i - n]] -= 1
76
+ if cnt1 == cnt2:
77
+ return True
78
+ return False
79
+ ```
80
+
81
+ ``` python
82
+ class Solution :
83
+ def checkInclusion (self , s1 : str , s2 : str ) -> bool :
84
+ n, m = len (s1), len (s2)
85
+ if n > m:
86
+ return False
87
+ cnt = Counter()
88
+ for a, b in zip (s1, s2):
89
+ cnt[a] -= 1
90
+ cnt[b] += 1
91
+ diff = sum (x != 0 for x in cnt.values())
92
+ if diff == 0 :
93
+ return True
94
+ for i in range (n, m):
95
+ a, b = s2[i - n], s2[i]
96
+
97
+ if cnt[b] == 0 :
98
+ diff += 1
99
+ cnt[b] += 1
100
+ if cnt[b] == 0 :
101
+ diff -= 1
102
+
103
+ if cnt[a] == 0 :
104
+ diff += 1
105
+ cnt[a] -= 1
106
+ if cnt[a] == 0 :
107
+ diff -= 1
108
+
109
+ if diff == 0 :
110
+ return True
76
111
return False
77
112
```
78
113
@@ -81,7 +116,226 @@ class Solution:
81
116
<!-- 这里可写当前语言的特殊实现逻辑 -->
82
117
83
118
``` java
119
+ class Solution {
120
+ public boolean checkInclusion (String s1 , String s2 ) {
121
+ int n = s1. length();
122
+ int m = s2. length();
123
+ if (n > m) {
124
+ return false ;
125
+ }
126
+ int [] cnt1 = new int [26 ];
127
+ int [] cnt2 = new int [26 ];
128
+ for (int i = 0 ; i < n; ++ i) {
129
+ ++ cnt1[s1. charAt(i) - ' a' ];
130
+ ++ cnt2[s2. charAt(i) - ' a' ];
131
+ }
132
+ if (Arrays . equals(cnt1, cnt2)) {
133
+ return true ;
134
+ }
135
+ for (int i = n; i < m; ++ i) {
136
+ ++ cnt2[s2. charAt(i) - ' a' ];
137
+ -- cnt2[s2. charAt(i - n) - ' a' ];
138
+ if (Arrays . equals(cnt1, cnt2)) {
139
+ return true ;
140
+ }
141
+ }
142
+ return false ;
143
+ }
144
+ }
145
+ ```
146
+
147
+ ``` java
148
+ class Solution {
149
+ public boolean checkInclusion (String s1 , String s2 ) {
150
+ int n = s1. length();
151
+ int m = s2. length();
152
+ if (n > m) {
153
+ return false ;
154
+ }
155
+ int [] cnt = new int [26 ];
156
+ for (int i = 0 ; i < n; ++ i) {
157
+ -- cnt[s1. charAt(i) - ' a' ];
158
+ ++ cnt[s2. charAt(i) - ' a' ];
159
+ }
160
+ int diff = 0 ;
161
+ for (int x : cnt) {
162
+ if (x != 0 ) {
163
+ ++ diff;
164
+ }
165
+ }
166
+ if (diff == 0 ) {
167
+ return true ;
168
+ }
169
+ for (int i = n; i < m; ++ i) {
170
+ int a = s2. charAt(i - n) - ' a' ;
171
+ int b = s2. charAt(i) - ' a' ;
172
+ if (cnt[b] == 0 ) {
173
+ ++ diff;
174
+ }
175
+ if (++ cnt[b] == 0 ) {
176
+ -- diff;
177
+ }
178
+ if (cnt[a] == 0 ) {
179
+ ++ diff;
180
+ }
181
+ if (-- cnt[a] == 0 ) {
182
+ -- diff;
183
+ }
184
+ if (diff == 0 ) {
185
+ return true ;
186
+ }
187
+ }
188
+ return false ;
189
+ }
190
+ }
191
+ ```
192
+
193
+ ### ** C++**
84
194
195
+ ``` cpp
196
+ class Solution {
197
+ public:
198
+ bool checkInclusion(string s1, string s2) {
199
+ int n = s1.size(), m = s2.size();
200
+ if (n > m) {
201
+ return false;
202
+ }
203
+ vector<int > cnt1(26), cnt2(26);
204
+ for (int i = 0; i < n; ++i) {
205
+ ++cnt1[ s1[ i] - 'a'] ;
206
+ ++cnt2[ s2[ i] - 'a'] ;
207
+ }
208
+ if (cnt1 == cnt2) {
209
+ return true;
210
+ }
211
+ for (int i = n; i < m; ++i) {
212
+ ++cnt2[ s2[ i] - 'a'] ;
213
+ --cnt2[ s2[ i - n] - 'a'] ;
214
+ if (cnt1 == cnt2) {
215
+ return true;
216
+ }
217
+ }
218
+ return false;
219
+ }
220
+ };
221
+ ```
222
+
223
+ ```cpp
224
+ class Solution {
225
+ public:
226
+ bool checkInclusion(string s1, string s2) {
227
+ int n = s1.size(), m = s2.size();
228
+ if (n > m) {
229
+ return false;
230
+ }
231
+ vector<int> cnt(26);
232
+ for (int i = 0; i < n; ++i) {
233
+ --cnt[s1[i] - 'a'];
234
+ ++cnt[s2[i] - 'a'];
235
+ }
236
+ int diff = 0;
237
+ for (int x : cnt) {
238
+ if (x) {
239
+ ++diff;
240
+ }
241
+ }
242
+ if (diff == 0) {
243
+ return true;
244
+ }
245
+ for (int i = n; i < m; ++i) {
246
+ int a = s2[i - n] - 'a';
247
+ int b = s2[i] - 'a';
248
+ if (cnt[b] == 0) {
249
+ ++diff;
250
+ }
251
+ if (++cnt[b] == 0) {
252
+ --diff;
253
+ }
254
+ if (cnt[a] == 0) {
255
+ ++diff;
256
+ }
257
+ if (--cnt[a] == 0) {
258
+ --diff;
259
+ }
260
+ if (diff == 0) {
261
+ return true;
262
+ }
263
+ }
264
+ return false;
265
+ }
266
+ };
267
+ ```
268
+
269
+ ### ** Go**
270
+
271
+ ``` go
272
+ func checkInclusion (s1 string , s2 string ) bool {
273
+ n , m := len (s1), len (s2)
274
+ if n > m {
275
+ return false
276
+ }
277
+ cnt1 := [26 ]int {}
278
+ cnt2 := [26 ]int {}
279
+ for i := range s1 {
280
+ cnt1[s1[i]-' a' ]++
281
+ cnt2[s2[i]-' a' ]++
282
+ }
283
+ if cnt1 == cnt2 {
284
+ return true
285
+ }
286
+ for i := n; i < m; i++ {
287
+ cnt2[s2[i]-' a' ]++
288
+ cnt2[s2[i-n]-' a' ]--
289
+ if cnt1 == cnt2 {
290
+ return true
291
+ }
292
+ }
293
+ return false
294
+ }
295
+ ```
296
+
297
+ ``` go
298
+ func checkInclusion (s1 string , s2 string ) bool {
299
+ n , m := len (s1), len (s2)
300
+ if n > m {
301
+ return false
302
+ }
303
+ cnt := [26 ]int {}
304
+ for i := range s1 {
305
+ cnt[s1[i]-' a' ]--
306
+ cnt[s2[i]-' a' ]++
307
+ }
308
+ diff := 0
309
+ for _ , x := range cnt {
310
+ if x != 0 {
311
+ diff++
312
+ }
313
+ }
314
+ if diff == 0 {
315
+ return true
316
+ }
317
+ for i := n; i < m; i++ {
318
+ a , b := s2[i-n]-' a' , s2[i]-' a'
319
+ if cnt[b] == 0 {
320
+ diff++
321
+ }
322
+ cnt[b]++
323
+ if cnt[b] == 0 {
324
+ diff--
325
+ }
326
+ if cnt[a] == 0 {
327
+ diff++
328
+ }
329
+ cnt[a]--
330
+ if cnt[a] == 0 {
331
+ diff--
332
+ }
333
+ if diff == 0 {
334
+ return true
335
+ }
336
+ }
337
+ return false
338
+ }
85
339
```
86
340
87
341
### ** TypeScript**
0 commit comments