1、题目描述
给定两个字符串 s
和 p
,找到 s
中所有 p
的 异位词的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
2、算法思路
异位词的长度是和p的长度是固定的。是连续的窗口,所以使用滑动窗口来解决,但是是固定大小的窗口。
并且使用count来记录窗口中的字母的种类和个数。当count中记录的种类和个数和p的种类和个数一样就可以更新结果。
3、算法流程
创建2个大小为26的数组,其中都是下标是0表示a,1表示b以此类推。hash1统计p中字符出现的种类和个数,hash2表示s出现的种类和个数。严格来说是用来记录窗口中的种类和个数。如果right的值比如是b,那么就寻找 hash2[right - 'a'] <= hash1[right - 'a'] 如果条件完成,就会表示目前是有效字符,count++。
比如 s aabc left = 0,right = 1
p abc
count = 1,因为p中的a只出现一次,所以有效字母值a也只能出现一次,才是有效字符,当right=0是count++了。
最后当count==p.length();//更新结果
4、算法代码
class Solution {
public List<Integer> findAnagrams(String s, String p) {
List<Integer> ret = new ArrayList<>();
char[] ss = s.toCharArray();
char[] pp = p.toCharArray();
int[] hash1 = new int[26];//统计p中的字符出现的个数
for (char ch : pp)hash1[ch - 'a']++;
int[] hash2 = new int[26];//统计s中字符出现的个数
int n = p.length(),m = s.length();//count用来统计滑动窗口中的有效字符
for (int left = 0,right = 0,count = 0;right < m;right++){
char into = ss[right];
//进窗口,然后判断right的元素在滑动窗口中的个数和对应的字符是否存在于p,如果是存在并且小于就count的有效字符++
if (++hash2[into - 'a'] <= hash1[into - 'a'])count++;//先++在比较大小
//判断,窗口的大小等于p的大小
if (right-left+1 > n){
char out = ss[left++];//先赋值在left++
if (hash2[out - 'a']-- <= hash1[out - 'a'])//先判断<=才可以减--,因为如果是2个连续的字符就只能算一个有效字符
count--;
}
//更新结果
if (count == n) ret.add(left);
}
return ret;
}
}