给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。字母异位词是通过重新排列不同单词或短语的字母而形成的单词或短语,并使用所有原字母一次。
示例 1:
输入: s = "cbaebabacd", p = "abc" 输出: [0,6] 解释: 起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。 起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
示例 2:
输入: s = "abab", p = "ab" 输出: [0,1,2] 解释: 起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。 起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。 起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。
提示:
1 <= s.length, p.length <= 3 * 104s和p仅包含小写字母
错误示例(超时)
class Solution {
public List<Integer> findAnagrams(String s, String p) {
List<Integer> result = new ArrayList<>();
//创造等于p的队列,转换为数组后排序比较
char[] char1 = s.toCharArray();
char[] char200 = p.toCharArray();
Character[] char2 = new Character[char200.length];
for (int i = 0; i < char200.length; i++) {
char2[i] = char200[i]; // 自动装箱
}
Queue<Character> queue = new LinkedList<>();
Arrays.sort(char2);
for(int i = 0;i<s.length();i++){
queue.offer(char1[i]);
if(queue.size()==p.length()){
Character[] char3 = queue.toArray(new Character[queue.size()]);
Arrays.sort(char3);
if(Arrays.equals(char2, char3)){
result.add(i-p.length()+1);
}
queue.poll();
}
}
return result;
}
}
正确结果
class Solution {
public List<Integer> findAnagrams(String s, String p) {
//滑动窗口问题,创建一个移动窗口,统计窗口内符合条件的字母
List<Integer> result = new ArrayList<>();
if(p.length()>s.length()){
return result;
}
int left = 0,right =0;
int slen =s.length(),plen =p.length();
int match = 0;
//创建26个小写字母的数组,索引就是对应顺序
int[] count = new int[26];
for(char c : p.toCharArray()){
count[c-'a']++;
}
while(right<slen){
//获取右指针所在位置处的索引
int rightIndex = s.charAt(right) - 'a';
if(count[rightIndex]>0){
match++;
}
count[rightIndex]--;
right++;
if(right-left == plen){
if(match==plen){
result.add(left);
}
//获取左指针所在位置处的索引
int leftIndex = s.charAt(left) - 'a';
if(count[leftIndex]>=0){
match--;
}
count[leftIndex]++;
left++;
}
}
return result;
}
}

