题目
题解一:暴力排序
依次截取三为排序好的字符串拿出来比较
// 方法一,暴力排序
List<Integer> res = new ArrayList<Integer>();
int n = s.length();
int k = p.length();
if (n < k) {
return res;
}
char[] chars = p.toCharArray();
Arrays.sort(chars);
p = new String(chars);
// 只需要遍历一次,排序进行比较
for (int i = 0; i <= n - k; i++) {
// 找到长度为k的子字符串
String temp = s.substring(i, i + k);
// 进行排序
chars = temp.toCharArray();
Arrays.sort(chars);
temp = new String(chars);
if (p.equals(temp)) {
res.add(i);
}
}
return res;
题解二:滑动窗口+记录字符出现次数
思路就是,设置两个数组,因为题目中说只包含小写字母,那么设置两个数组长度为26的数组,一个用于存放比较的串,一个用于滑动窗口的串
p.charAt(i)-'a'其实就代表i元素在这个数组的位置,那么只需记录固定窗口下的 字母出现的个数,与比较的串相比较
如p="abc",则pindex为[1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
如过滑动的窗口元素是p="cba",sindex[1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
//方法二 滑动窗口
int plen = p.length();
int slen = s.length();
List<Integer> list = new ArrayList<>();
int[] pindex = new int[26];
int[] sindex = new int[26];
if(slen<plen){
return list;
}
//如p="abc",则pindex为[1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
//如过滑动的窗口元素是p="cba",sindex[1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
// 这两个就是异位次 原理就是记录字母出现的次数,转换成出现的位置的索引值
// abc[1,1,1,....] 索引 0 1 2 位置的值就是字母abc出现的次数值
//假设需要匹配的字符串为cbc[0,1,2,....] a 0个,b 1个,c 2个,明细不匹配
//当滑动窗口的首位在s[0]处时 (相当于放置滑动窗口进入数组)
for(int i = 0;i<plen;i++){
pindex[p.charAt(i)-'a']++;//记录要寻找的字符串中每个字母的词频(只用进行一次来确定)
sindex[s.charAt(i)-'a']++;//记录s中前pLen个字母的词频
}
//判断放置处是否有异位词 (在放置时只需判断一次)
if(Arrays.equals(pindex,sindex)) list.add(0);
//开始让窗口进行滑动
for(int i = 1;i<=slen-plen;i++){
sindex[s.charAt(i-1)-'a']--;
sindex[s.charAt(i+plen-1)-'a']++;
//判断滑动后处,是否有异位词
if(Arrays.equals(pindex,sindex)){
list.add(i);
}
}
return list;