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

发布于:2025-09-12 ⋅ 阅读:(17) ⋅ 点赞:(0)

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        List<Integer> result = new ArrayList<>();
        int sLen = s.length();
        int pLen = p.length();
        //边界判断
        if (sLen < pLen) {
            return result;
        }
        //1.对p进行字符频率统计,并且计算p中字符个数
        int pCount = 0;
        Map<Character, Integer> pMap = new HashMap<>();
        for (char c : p.toCharArray()) {
            if (!pMap.containsKey(c)) {
                pCount++;
            }
            pMap.put(c, pMap.getOrDefault(c, 0) + 1);
        }
        //2.求解第一个窗口中是否有异位词
        int sCount = 0;
        Map<Character, Integer> sMap = new HashMap<>();
        for (int i = 0; i < pLen; i++) {
            char ch = s.charAt(i);
            if (pMap.containsKey(ch)) {
                sMap.put(ch, sMap.getOrDefault(ch, 0) + 1);
                if (sMap.get(ch).equals(pMap.get(ch))) {
                    sCount++;
                }
            }
        }
        if (pCount == sCount) {
            result.add(0);
        }
        //3.滑动窗口遍历剩余字符
        for (int i = pLen; i < sLen; i++) {
            //3.1添加窗口右侧新字符
            char rightChar = s.charAt(i);
            if (pMap.containsKey(rightChar)) {
                sMap.put(rightChar, sMap.getOrDefault(rightChar, 0) + 1);
                if (sMap.get(rightChar).equals(pMap.get(rightChar))) {
                    sCount++;
                }
            }
            //3.2移除窗口左侧旧字符
            char leftChar = s.charAt(i - pLen);
            if (pMap.containsKey(leftChar)) {
                //3.2.1左侧旧字符移除后恰好有一个字符不匹配了,那么scount-1
                if (sMap.get(leftChar).equals(pMap.get(leftChar))) {
                    sCount--;
                }
                //3.2.2左侧旧字符移除后这个词频为0,那么这个字符该从词典中移除,不为0则词频-1
                int leftCount = sMap.get(leftChar);
                if (leftCount == 1) {
                    sMap.remove(leftChar);
                } else {
                    sMap.put(leftChar, leftCount - 1);
                }
            }
            //3.3判断当前窗口的单词是否是异位词
            if (sCount == pCount) {
                result.add(i - pLen + 1);
            }
        }
        //4.结果返回
        return result;
    }
}


网站公告

今日签到

点亮在社区的每一天
去签到