https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/

    1. class Solution {
    2. public List<Integer> findAnagrams(String s, String p) {
    3. // 暴力法
    4. // 时间:O(N) 空间:O(1)
    5. // 定义一个结果列表
    6. ArrayList<Integer> resList = new ArrayList<>();
    7. // 统计目标 p 字符的频次
    8. int[] targetArrayCounts = new int[26];
    9. for (int i = 0; i < p.length(); i++) {
    10. targetArrayCounts[p.charAt(i) - 'a']++;
    11. }
    12. // 遍历 s,以每一个字符作为起始,考察长度为 p.length 的子串
    13. for (int i = 0; i < s.length() - p.length() + 1; i++) {
    14. // 判断当前子串是否为 p 的字母异位次
    15. boolean isMatched = true;
    16. // 定义一个数组,统计子串中所有字符频次
    17. int[] subStringCounts = new int[26];
    18. for (int j = i; j < i + p.length(); j++) {
    19. // subStringCounts 中的频次首先加一,然后直接判断,字符频次超过 p 中的字符频次,直接不符合
    20. if (++subStringCounts[s.charAt(j) - 'a'] > targetArrayCounts[s.charAt(j) - 'a']) {
    21. isMatched = false;
    22. break;
    23. }
    24. }
    25. if (isMatched == true) {
    26. resList.add(i);
    27. }
    28. }
    29. return resList;
    30. }
    31. }
    1. class Solution {
    2. public List<Integer> findAnagrams(String s, String p) {
    3. // 滑动窗口,时间效率上是上一个方法的100倍
    4. // 时间:O(2 * N) 空间:O(1)
    5. // 定义一个结果列表
    6. ArrayList<Integer> resList = new ArrayList<>();
    7. // 统计目标 p 字符的频次
    8. int[] targetArrayCounts = new int[26];
    9. for (int i = 0; i < p.length(); i++) {
    10. targetArrayCounts[p.charAt(i) - 'a']++;
    11. }
    12. // 定义一个数组,统计子串中所有字符频次
    13. int[] subStringCounts = new int[26];
    14. // 定义左右指针,右不包含
    15. int start = 0, end = 1;
    16. // 移动指针,总是截取字符出现频次全部小于等于 p 中字符频次的子串
    17. while (end <= s.length()) {
    18. char newChar = s.charAt(end - 1);
    19. subStringCounts[newChar - 'a']++;
    20. // 判断当前子串是否符合要求
    21. // 如果新增字符导致子串中频次超过了 p 中的频次,那么移动 start,消除新增字符的影响
    22. while (subStringCounts[newChar - 'a'] > targetArrayCounts[newChar - 'a'] && start < end) {
    23. // 在 start 右移同时,伴随着这个字符频次减少的操作
    24. char removeChar = s.charAt(start);
    25. subStringCounts[removeChar - 'a']--;
    26. start++;
    27. }
    28. // 如果当前子串长度等于 p 子串的长度,那么就是一个字母异位词
    29. if (end - start == p.length()) {
    30. resList.add(start);
    31. }
    32. end++;
    33. }
    34. return resList;
    35. }
    36. }