438. Find All Anagrams in a String
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".
方法0: Brute force TLE
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
if (s.empty() || p.empty()) return {};
unordered_map<char, int> hash;
for (char c: p) hash[c]++;
unordered_map<char, int> copy(hash);
vector<int> result;
for (int i = 0; i <= (int)(s.size() - p.size()); i++) {
copy.clear();
int j = 0;
for (; j < p.size(); j ++) {
copy[s[i + j]]++;
if (copy[s[i + j]] > hash[s[i + j]]) break;
}
if (j == p.size()) result.push_back(i);
}
return result;
}
};
方法1: sliding window
Complexity
Time complexity: O(n)
Space complexity: O(n)
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
if (s.empty() || p.empty()) return {};
int n = s.size();
int m = p.size();
vector<int> hash(26, 0);
vector<int> copy(26, 0);
vector<int> result;
for (char c: p) hash[c - 'a']++;
for (int i = 0; i < n ; i++) {
if (i >= p.size()) copy[s[i - m] - 'a']--;
copy[s[i] - 'a']++;
if (hash == copy) result.push_back(i - m + 1);
}
return result;
}
};