问题:
难度:easy
说明:
输入字符串s,p,然后在s中查找所有符合p的异序词,返回异序词开头索引。
输入案例:
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".
我的代码:
首先想到就是把p的字符记录到hashmap里面,然后每次进来一个就减去1,完成了之后就添加开头index,否则进行下一个,然后hashmap里面的数据都要复位,但是代码跑了600多ms。
public List<Integer> findAnagrams2(String s, String p) {
int len = s.length();
char[] sc = s.toCharArray();
int plen = p.length();
char[] pc = p.toCharArray();
int[] map = new int[26];
List<Integer> findList = new ArrayList<Integer>();
// 放hashmap
for(int i = 0;i < plen;i ++) {
map[pc[i] - 'a'] ++;
}
for(int i = 0;i < len;i ++) {
if(p.indexOf(sc[i]) != -1) {
// 每次需要重新拿一个数组
int[] temp = Arrays.copyOf(map, 26);
int index = 0;
// 连续查找
for(int j = i;j < len;j ++) {
int ji = sc[j] - 'a';
// 发现不适合就跳出
if(temp[ji] == 0) break;
temp[ji] --;
index ++;
// 如果发现连续长度已经足够,就添加
if(index == plen) {
findList.add(i);
}
}
}
}
return findList;
}
其它代码:
滑动窗口代码,这个真的好多了,时间复杂度就On:
public List<Integer> findAnagrams(String s, String p) {
List<Integer> res = new ArrayList<>();
// 双指针
int left=0;
int right=0;
int[] counts = new int[128];
// 放入hashmap进行统计
for(char x: p.toCharArray()){
counts[x] ++;
}
// left会根据right移动到不存在的点而移动
// 并且left作为开头,让right和left的区间锁定适合p的乱序字符
// -1就是不存在,然后left会移动并且填补(就是+1的意思)
while(right<s.length()){
counts[s.charAt(right)] --;
while(counts[s.charAt(right)] < 0){
counts[s.charAt(left ++)] ++;
}
right ++;
if(right-left==p.length())res.add(left);
}
return res;
}