438. 找到字符串中所有字母异位词

image

438. 找到字符串中所有字母异位词

思路

滑动窗口 + 数组(字符计数)

  1. 使用两个固定长度的数组(长度为 26,代表英文字母 a-z)分别记录:

    • p 中各字符的频率;
    • 当前窗口中各字符的频率;
  2. 遍历 s,滑动长度为 len(p) 的窗口,比较窗口内字符频率是否与 p 的一致;

  3. 如果一致,记录窗口起始索引。

复杂度分析

  • 时间复杂度:O(n),其中 n 是字符串 s 的长度;
  • 空间复杂度:O(1),因为字符集是固定的(26个字母)。

代码

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        List<Integer> res = new ArrayList<>();
        int sLen = s.length();
        int pLen = p.length();
        if (pLen > sLen) {
            return res;
        }

        // 使用26长度的数组存放字母个数
        int[] pCount = new int[26]; // p的字符统计
        int[] wCount = new int[26]; // 滑动窗口的字符统计

        // 初始化 p 的字符计数
        for (char pChar : p.toCharArray()) {
            pCount[pChar - 'a']++;
        }
        
        // 先统计第一个窗口
        for (int i = 0; i < pLen; i++) {
            wCount[s.charAt(i) - 'a']++;
        }
        if (Arrays.equals(pCount, wCount)) {
            res.add(0);
        }

        for (int right = pLen; right < sLen; right++) {
            // 左边界的字符(即将移出窗口的字符)
            char leftChar = s.charAt(right - pLen);
            // 右边界的字符(即将移入窗口的字符)
            char rightChar = s.charAt(right);

            wCount[leftChar - 'a']--;
            wCount[rightChar - 'a']++;

            // 窗口的起始索引
            int startIndex = right - pLen + 1;
            if (Arrays.equals(pCount, wCount)) {
                res.add(startIndex);
            }
        }
        return res;
    }
}
posted @ 2025-08-09 00:48  quanht  阅读(11)  评论(0)    收藏  举报