给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。
提示:
1 <= s.length, p.length <= 3 * 10^4
s
和p
仅包含小写字母
1、使用数组
-
class Solution { public List<Integer> findAnagrams(String s, String p) { List<Integer> list = new ArrayList<>(); int n = s.length(),m = p.length(); if(n < m){ return list; } int[] sCnt = new int[26]; int[] pCnt = new int[26]; //将前m个元素加入到对应数组进行比较,如果相等则返回零 for(int i = 0;i < m;i++){ sCnt[s.charAt(i) - 'a']++; pCnt[p.charAt(i) - 'a']++; } if(Arrays.equals(sCnt,pCnt)){ list.add(0); } //将后续的元素加入到第一个数组,同时加入一个就从原来的数组取出一个 for(int i = m;i < n;i++){ sCnt[s.charAt(i - m) - 'a']--; sCnt[s.charAt(i) - 'a']++; //pCnt[p.charAt(i) - 'a']++; if(Arrays.equals(sCnt,pCnt)){ list.add(i - m + 1); } } return list; } }
7ms;42.6MB
-
2、数组加双指针
-
class Solution { public List<Integer> findAnagrams(String s, String p) { List<Integer> list = new ArrayList<>(); int n = s.length(),m = p.length(); if(n < m){ return list; } int[] sCnt = new int[26]; int[] pCnt = new int[26]; //将前p的前所有元素加入到对应数组 for(int i = 0;i < m;i++){ pCnt[p.charAt(i) - 'a']++; } //使用双指针left,right int left = 0; for(int right = 0;right < n;right++){ int curRight = s.charAt(right) - 'a'; sCnt[curRight]++; //如果当前s中右指针的值的个数大于p中该值的个数,将左指针右移直到个数不大于 while(sCnt[curRight] > pCnt[curRight]){ int curLeft = s.charAt(left) - 'a'; sCnt[curLeft]--; left++; } //当两个数组相等,则说明内容相等 if((right - left + 1) == m){ list.add(left); } } return list; } }
4ms;42.6MB