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". 两种方法: 第一种: 用两个map,m1,m2. m1存p,m2动态存,首先先存s的前p.size个元素,判断两个hash表相等与否,相等就可以push_back开始的位置。 第二种: 滑动窗口的方法。left,right表示左右边界,cnt表示窗口的长度。窗口内的字符就是已经匹配上的字符,所以,当cnt==p.size()的时候就可以push_back(left) left和right相当于两个指针,最终left和right都会走完一遍字符串s。走的路径跟第一种方法其实思想是一样的: 1 if (m[s[right]]>0) 那么m[s[right]]--表示匹配上了一个,然后right++,cnt++,即右边界右移一个2 if (m[s[right]]<=0) 说明没匹配上,那么就该left移动了。 3 最后判断cnt==p.size() 代码如下: 1、 省略了,比较简单。 2、 vector<int> findAnagrams(string s, string p) { map<char, int> m; int left = 0, right = 0, cnt = 0; vector<int> res; if (s.size() < p.size()) return res; for (char c : p) m[c]++; while (right < s.size()){ if (m[s[right]]>0){ m[s[right++]]--; cnt++; } else{ if (left == right){ left++; right++; } else{ ++m[s[left++]]; cnt--; } } if (cnt == p.size()){ res.push_back(left); ++m[s[left++]]; cnt--; } } return res; }