Skip to content

Commit 11b6e20

Browse files
committed
feat: add solutions to leetcode problem: No.0438. Find All Anagrams in a String
1 parent 555bfd5 commit 11b6e20

File tree

4 files changed

+149
-26
lines changed

4 files changed

+149
-26
lines changed

solution/0400-0499/0438.Find All Anagrams in a String/README.md

+72-2
Original file line numberDiff line numberDiff line change
@@ -46,27 +46,97 @@ s: "abab" p: "ab"
4646
起始索引等于 2 的子串是 "ab", 它是 "ab" 的字母异位词。
4747
</pre>
4848

49-
5049
## 解法
5150

5251
<!-- 这里可写通用的实现逻辑 -->
5352

53+
“双指针 + 滑动窗口”求解。定义滑动窗口的左右两个指针 left、right,right 一步步往右走遍历 s 字符串,当 right 指针遍历到的字符加入 t 后超过 counter 的字符数量时,将滑动窗口左侧字符不断弹出,也就是 left 指针不断右移,直到符合要求为止。
54+
55+
若滑动窗口长度等于字符串 p 的长度时,这时的 s 子字符串就是 p 的异位词。
56+
5457
<!-- tabs:start -->
5558

5659
### **Python3**
5760

5861
<!-- 这里可写当前语言的特殊实现逻辑 -->
5962

6063
```python
61-
64+
class Solution:
65+
def findAnagrams(self, s: str, p: str) -> List[int]:
66+
counter = collections.Counter(p)
67+
res = []
68+
left = right = 0
69+
t = collections.Counter()
70+
while right < len(s):
71+
t[s[right]] += 1
72+
while t[s[right]] > counter[s[right]]:
73+
t[s[left]] -= 1
74+
left += 1
75+
if right - left == len(p) - 1:
76+
res.append(left)
77+
right += 1
78+
return res
6279
```
6380

6481
### **Java**
6582

6683
<!-- 这里可写当前语言的特殊实现逻辑 -->
6784

85+
“暴力”求解。利用哈希表 counter 统计字符串 p 中每个字符出现的次数。然后遍历字符串 s,判断子串 `s[i, i + p)` 中每个字符出现的次数是否与 counter 相同。若是,则将当前下标 i 添加到结果列表中。时间复杂度 `O(s.length * p.length)`
86+
6887
```java
88+
class Solution {
89+
public List<Integer> findAnagrams(String s, String p) {
90+
int[] counter = new int[26];
91+
for (int i = 0; i < p.length(); ++i) {
92+
++counter[p.charAt(i) - 'a'];
93+
}
94+
List<Integer> res = new ArrayList<>();
95+
for (int i = 0; i <= s.length() - p.length(); ++i) {
96+
int[] t = Arrays.copyOf(counter, counter.length);
97+
boolean find = true;
98+
for (int j = i; j < i + p.length(); ++j) {
99+
if (--t[s.charAt(j) - 'a'] < 0) {
100+
find = false;
101+
break;
102+
}
103+
}
104+
if (find) {
105+
res.add(i);
106+
}
107+
}
108+
return res;
109+
}
110+
}
111+
```
69112

113+
“双指针 + 滑动窗口”求解。
114+
115+
```java
116+
class Solution {
117+
public List<Integer> findAnagrams(String s, String p) {
118+
int[] counter = new int[26];
119+
for (int i = 0; i < p.length(); ++i) {
120+
++counter[p.charAt(i) - 'a'];
121+
}
122+
List<Integer> res = new ArrayList<>();
123+
int left = 0, right = 0;
124+
int[] t = new int[26];
125+
while (right < s.length()) {
126+
int i = s.charAt(right) - 'a';
127+
++t[i];
128+
while (t[i] > counter[i]) {
129+
--t[s.charAt(left) - 'a'];
130+
++left;
131+
}
132+
if (right - left == p.length() - 1) {
133+
res.add(left);
134+
}
135+
++right;
136+
}
137+
return res;
138+
}
139+
}
70140
```
71141

72142
### **...**

solution/0400-0499/0438.Find All Anagrams in a String/README_EN.md

+39-2
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,50 @@ The substring with start index = 2 is &quot;ab&quot;, which is an anagram of &qu
4444
### **Python3**
4545

4646
```python
47-
47+
class Solution:
48+
def findAnagrams(self, s: str, p: str) -> List[int]:
49+
counter = collections.Counter(p)
50+
res = []
51+
left = right = 0
52+
t = collections.Counter()
53+
while right < len(s):
54+
t[s[right]] += 1
55+
while t[s[right]] > counter[s[right]]:
56+
t[s[left]] -= 1
57+
left += 1
58+
if right - left == len(p) - 1:
59+
res.append(left)
60+
right += 1
61+
return res
4862
```
4963

5064
### **Java**
5165

5266
```java
53-
67+
class Solution {
68+
public List<Integer> findAnagrams(String s, String p) {
69+
int[] counter = new int[26];
70+
for (int i = 0; i < p.length(); ++i) {
71+
++counter[p.charAt(i) - 'a'];
72+
}
73+
List<Integer> res = new ArrayList<>();
74+
int left = 0, right = 0;
75+
int[] t = new int[26];
76+
while (right < s.length()) {
77+
int i = s.charAt(right) - 'a';
78+
++t[i];
79+
while (t[i] > counter[i]) {
80+
--t[s.charAt(left) - 'a'];
81+
++left;
82+
}
83+
if (right - left == p.length() - 1) {
84+
res.add(left);
85+
}
86+
++right;
87+
}
88+
return res;
89+
}
90+
}
5491
```
5592

5693
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Solution {
2+
public List<Integer> findAnagrams(String s, String p) {
3+
int[] counter = new int[26];
4+
for (int i = 0; i < p.length(); ++i) {
5+
++counter[p.charAt(i) - 'a'];
6+
}
7+
List<Integer> res = new ArrayList<>();
8+
int left = 0, right = 0;
9+
int[] t = new int[26];
10+
while (right < s.length()) {
11+
int i = s.charAt(right) - 'a';
12+
++t[i];
13+
while (t[i] > counter[i]) {
14+
--t[s.charAt(left) - 'a'];
15+
++left;
16+
}
17+
if (right - left == p.length() - 1) {
18+
res.add(left);
19+
}
20+
++right;
21+
}
22+
return res;
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,15 @@
11
class Solution:
2-
def findAnagrams(self, s, p):
3-
"""
4-
:type s: str
5-
:type p: str
6-
:rtype: List[int]
7-
"""
8-
lens=len(s)
9-
lenp=len(p)
10-
if lens < lenp:
11-
return []
12-
flag1 = [0] * 26
13-
flag2 = [0] * 26
14-
for i, x in enumerate(p):
15-
flag1[ord(x) - 97] += 1
16-
ans = []
17-
for i, x in enumerate(s):
18-
flag2[ord(x)- 97] += 1
19-
if i >= lenp:
20-
flag2[ord(s[i - lenp]) - 97] -= 1
21-
if flag1 == flag2:
22-
ans.append(i-lenp+1)
23-
return ans
2+
def findAnagrams(self, s: str, p: str) -> List[int]:
3+
counter = collections.Counter(p)
4+
res = []
5+
left = right = 0
6+
t = collections.Counter()
7+
while right < len(s):
8+
t[s[right]] += 1
9+
while t[s[right]] > counter[s[right]]:
10+
t[s[left]] -= 1
11+
left += 1
12+
if right - left == len(p) - 1:
13+
res.append(left)
14+
right += 1
15+
return res

0 commit comments

Comments
 (0)