Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e030d3e

Browse files
committed
feat: add solutions to lc problem: No.0567
No.0567.Permutation in String
1 parent 94b6982 commit e030d3e

File tree

6 files changed

+687
-92
lines changed

6 files changed

+687
-92
lines changed

‎solution/0500-0599/0567.Permutation in String/README.md‎

Lines changed: 278 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,22 @@
4040

4141
<!-- 这里可写通用的实现逻辑 -->
4242

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+
4359
<!-- tabs:start -->
4460

4561
### **Python3**
@@ -49,30 +65,49 @@
4965
```python
5066
class Solution:
5167
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
76111
return False
77112
```
78113

@@ -81,7 +116,226 @@ class Solution:
81116
<!-- 这里可写当前语言的特殊实现逻辑 -->
82117

83118
```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++**
84194

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+
}
85339
```
86340

87341
### **TypeScript**

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /