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

java 复制代码
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;
    }
}
相关推荐
参.商.2 小时前
【Day41】143. 重排链表
leetcode·golang
Zaly.5 小时前
【Python刷题】LeetCode 1727 重新排列后的最大子矩阵
算法·leetcode·矩阵
memcpy08 小时前
LeetCode 1456. 定长子串中元音的最大数目【定长滑窗模板题】中等
算法·leetcode·职场和发展
玛丽莲茼蒿8 小时前
LeetCode hot100【相交链表】【简单】
算法·leetcode·职场和发展
罗湖老棍子8 小时前
They Are Everywhere(Codeforces- P701C)
算法·滑动窗口·codeforce题解
wen__xvn8 小时前
力扣模拟题刷题
算法·leetcode
不要秃头的小孩8 小时前
力扣刷题——111.二叉树的最小深度
数据结构·python·算法·leetcode
We་ct9 小时前
LeetCode 35. 搜索插入位置:二分查找的经典应用
前端·算法·leetcode·typescript·个人开发
Navigator_Z10 小时前
LeetCode //C - 990. Satisfiability of Equality Equations
c语言·算法·leetcode
lightqjx11 小时前
【算法】前缀和
c++·算法·leetcode·前缀和