题目
题解一:暴力排序
依次截取三为排序好的字符串拿出来比较
// 方法一,暴力排序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;