public List<Integer> findAnagrams(String s, String p) {
List<Integer> result = new ArrayList<Integer>();
//构造P的map
int[] mapP = new int[26];
for(int i = 0, len = p.length(); i < len; i++) {
mapP[p.charAt(i) - 'a']++;
}
int[] mapS = new int[26];
int begin = 0;
for(int i = 0, len = s.length(); i < len; i++) {
mapS[s.charAt(i) - 'a']++;
if(isWindowOK(mapS, mapP)) {
result.add(begin);
mapS[s.charAt(begin) - 'a']--;
begin++;
} else if(mapP[s.charAt(i) - 'a'] == 0){
while(begin <= i) {
mapS[s.charAt(begin) - 'a']--;
begin++;
}
} else if(i - begin == p.length() - 1) {
mapS[s.charAt(begin) - 'a']--;
begin++;
}
}
return result;
}
public boolean isWindowOK(int[] mapS, int[] mapP) {
for(int i = 0; i < 26; i++) {
if(mapS[i] != mapP[i]) {
return false;
}
}
return true;
}
这题的关键点:
1.双指针维护区间,条件是区间内的字符串与子串的字符序列相同,即不看顺序,只要字符串有相同字符且字符个数相同就行。这样我们就可以利用map数组纪录字符个数,再比较数组。
2.当区间字符串的字符在子串未出现,或者区间字符串的长度等于子串长度但不满足相同字符且字符个数相同,或者区间满足条件时,begin才开始移动,并且移动过程中把begin位置字符从mapS中减去。