解题思路:滑动窗口
代码(Java):
解法1 (复杂版):
class Solution {
public List<Integer> findAnagrams(String s, String p) {
int p1 = 0;
int p2 = 0;
HashMap<Character,Integer> map = new HashMap<>();
List<Integer> list = new ArrayList<>();
for(char c : p.toCharArray()){
if(!map.containsKey(c)){
map.put(c,1);
}else{
map.put(c,map.get(c)+1);
}
}
// slid window
// Notice: counter increase and decrease situation
int counter = map.size();
while(p2 < s.length()){
char c = s.charAt(p2);
if(map.containsKey(c)){
map.put(c,map.get(c)-1);
if(map.get(c) == 0)counter--;
}
p2++;
while(counter == 0){
char temp = s.charAt(p1);
if(map.containsKey(temp)){
map.put(temp,map.get(temp)+1);
if(map.get(temp) > 0) counter++;
}
if(p2-p1 == p.length()){
list.add(p1);
}
p1++;
}
}
return list;
}
}
解法2 (精简版):
class Solution {
public List<Integer> findAnagrams(String s, String p) {
List<Integer> result = new ArrayList<>();
// counter the 26 characters in p string
int[] char_counts = new int[26];
for(char c: p.toCharArray()){
char_counts[c - 'a']++;
}
// slid window
int left = 0;
int right = 0;
int counter = p.length();
while(right < s.length()){
if(char_counts[s.charAt(right++)-'a']-- > 0){
counter--;
}
if(counter == 0){
result.add(left);
}
if(right - left == p.length() && (char_counts[s.charAt(left++)-'a']++ >= 0)){
counter++;
}
}
return result;
}
}
总体思路都是对p里面的字符进行计数,在滑动窗口的时候判断是否都存在p的字符,且字符出现的次数是否一致,以及字符长度是否一致。在出现这种情况,在进行更新左边窗口之前,将当前左边窗口的位置添加到result数组中。