题目描述:
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".
找出字符串的所有的子字符串,使得它们是目标字符串的异位字符串。直接以字符串中每个字符作为起点,然后判断,需要O(n*p.size()),但是利用滑动窗口可以降低到O(n)的时间复杂度。用left,right变量标记当前子字符串的左右位置,定义一个变量count表示子字符串和p之间相差的字母数,用哈希表存储子字符串和p中每个字母的次数差距。每次循环先移动right,并更新哈希表和count,同时保持子字符串的长度不能超过p,否则就要移动left减小子字符串的长度。当子字符串已经包含p的所有字母之后,此时count为0,就得到了一个结果。
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> result;
if(s.size()==0||p.size()==0) return result;
int left=0;
int right=0;
int count=p.size();
vector<int> hash(256,0);
for(int i=0;i<p.size();i++) hash[p[i]]++;
while(right<s.size())
{
#判断s[right]是否为p中元素,并更新count和hash,然后移动right
if(hash[s[right]]>=1) count--;
hash[s[right]]--;
right++;
#当count为0,说明已经找到了一个结果
if(count==0) result.push_back(left);
#当滑动窗口的长度已经等于p的长度时,需要更新count和hash,然后移动left
if(right-left==p.size())
{
if(hash[s[left]]>=0) count++;
hash[s[left]]++;
left++;
}
}
return result;
}
};