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".
代码
Approach #1 Sliding Window with HashMap
Complexity Analysis
Time complexity: O(Ns+Np) since it's one pass along both strings.
Space complexity: O(1), because pCount and sCount contain not more than 26 elements.
classSolution {publicList<Integer> findAnagrams(String s,String p) {int ns =s.length(), np =p.length();if (ns < np) returnnewArrayList();Map<Character,Integer> pCount =newHashMap();Map<Character,Integer> sCount =newHashMap();// build reference hashmap using string pfor (char ch :p.toCharArray()) {if (pCount.containsKey(ch)) {pCount.put(ch,pCount.get(ch) +1); }else {pCount.put(ch,1); } }List<Integer> output =newArrayList();// sliding window on the string sfor (int i =0; i < ns; ++i) {// add one more letter // on the right side of the windowchar ch =s.charAt(i);if (sCount.containsKey(ch)) {sCount.put(ch,sCount.get(ch) +1); }else {sCount.put(ch,1); }// remove one letter // from the left side of the windowif (i >= np) { ch =s.charAt(i - np);if (sCount.get(ch) ==1) {sCount.remove(ch); }else {sCount.put(ch,sCount.get(ch) -1); } }// compare hashmap in the sliding window// with the reference hashmapif (pCount.equals(sCount)) {output.add(i - np +1); } }return output; }}