
【暴力】用数组统计p中各个字母的出现次数,从头到尾匹配,相当于一个变长带限制的滑动窗口,O(n^2)的时间复杂度,勉强能过。
- class Solution {
- public List<Integer> findAnagrams(String s, String p) {
- List<Integer> ans = new ArrayList();
- int m = s.length(), n = p.length(), l = m - n, j;
- int[] cnt = new int[26];
- for(var i = 0; i < n; i++) cnt[p.charAt(i) - 'a']++;
- for(var i = 0; i <= l; i++){
- boolean flag = true;
- int[] tmp = cnt.clone();
- for(j = 0; j < n; j++){
- char c = s.charAt(i + j);
- if(tmp[c - 'a'] == 0){
- flag = false; break;
- }else{
- tmp[c - 'a']--;
- }
- }
- if(flag) ans.add(i);
- }
- return ans;
- }
- }
【滑动窗口】 定长滑动窗口,统计p长度的窗口内字符的个数,每次移动时把前面字符去掉,再加上后面的字符,与p中字符个数进行比对,时间复杂度降到O(n*26)
- class Solution {
-
- // 滑动窗口 1:28
-
- public List<Integer> findAnagrams(String s, String p) {
- int m = s.length(), n = p.length(), l = m - n;
- int[] cnt = new int[26], wd = new int[26];
- List<Integer> ans = new ArrayList();
- if(m < n) return ans;
- for(var i = 0; i < n; i++) cnt[p.charAt(i) - 'a']++;
- for(var i = 0; i < n; i++) wd[s.charAt(i) - 'a']++;
- if(Arrays.equals(cnt, wd)) ans.add(0);
- for(var i = n; i < m; i++){
- wd[s.charAt(i - n) - 'a']--;
- wd[s.charAt(i) - 'a']++;
- if(Arrays.equals(cnt, wd)) ans.add(i - n + 1);
- }
- return ans;
- }
- }