Description
Given a string s and a non-empty string p, find all the start indices of p’s anagrams in s.
Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.
The order of output does not matter.
Example 1:
Input:
s: "cbaebabacd" p: "abc"
Output:
[0, 6]
Explanation:
The substring with start index = 0 is "cba", which is an anagram of "abc".
The substring with start index = 6 is "bac", which is an anagram of "abc".
Example 2:
Input:
s: "abab" p: "ab"
Output:
[0, 1, 2]
Explanation:
The substring with start index = 0 is "ab", which is an anagram of "ab".
The substring with start index = 1 is "ba", which is an anagram of "ab".
The substring with start index = 2 is "ab", which is an anagram of "ab".
分析
题目的意思是:给你两个字符串s,p,要求在s中找出所有p的变体(字符串序可以不一样,字符一样)的位置。
首先统计字符串p中字符出现的次数,然后从s的开头开始,每次找p字符串长度个字符,来验证字符个数是否相同,如果不相同出现了直接break,如果一直都相同了,则将起始位置加入结果res中
- 这算是暴力破解的一个题目了,一看到字符串的题目,如果不考虑顺序,hash表是一个常用的方法。
C++
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
if(s.empty()) return {};
vector<int> result;
vector<int> cnt(128,0);
for(char c:p){
cnt[c]++;
}
for(int i=0;i<s.size();i++){
vector<int> temp=cnt;
bool success=true;
for(int j=i;j<i+p.size();j++){
if(temp[s[j]]>0){
temp[s[j]]--;
}else{
success=false;
break;
}
}
if(success){
result.push_back(i);
}
}
return result;
}
};
Python
滑动窗口+Counter简直是绝了,比我当时一个一个遍历(超时)的去判断好多了。
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
# Counter count, sliding_window
p_counter = Counter(p)
window_counter = Counter(s[:len(p)])
res = []
for i in range(len(s)-len(p)+1):
if p_counter==window_counter:
res.append(i)
window_counter[s[i]]-=1
if window_counter[s[i]]==0:
del window_counter[s[i]]
if i+len(p)<len(s):
window_counter[s[i+len(p)]]+=1
return res
或者下面的写法也是可以的:
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
p_counter = Counter(p)
window_counter = Counter(s[:len(p)])
res = []
if p_counter==window_counter:
res.append(0)
for i in range(len(p),len(s)):
window_counter[s[i]]+=1
window_counter[s[i-len(p)]]-=1
if window_counter[s[i-len(p)]]==0:
del window_counter[s[i-len(p)]]
if window_counter==p_counter:
res.append(i-len(p)+1)
return res