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;
    }
}
相关推荐
历程里程碑1 天前
普通数组----合并区间
java·数据结构·python·算法·leetcode·职场和发展·tornado
iAkuya1 天前
(leetcode)力扣100 61分割回文串(回溯,动归)
算法·leetcode·职场和发展
VT.馒头1 天前
【力扣】2695. 包装数组
前端·javascript·算法·leetcode·职场和发展·typescript
Charlie_lll1 天前
力扣解题-移动零
后端·算法·leetcode
iAkuya1 天前
(leetcode)力扣100 62N皇后问题 (普通回溯(使用set存储),位运算回溯)
算法·leetcode·职场和发展
YuTaoShao1 天前
【LeetCode 每日一题】3634. 使数组平衡的最少移除数目——(解法一)排序+滑动窗口
算法·leetcode·排序算法
TracyCoder1231 天前
LeetCode Hot100(27/100)——94. 二叉树的中序遍历
算法·leetcode
草履虫建模2 天前
力扣算法 1768. 交替合并字符串
java·开发语言·算法·leetcode·职场和发展·idea·基础
VT.馒头2 天前
【力扣】2721. 并行执行异步函数
前端·javascript·算法·leetcode·typescript
不穿格子的程序员2 天前
从零开始写算法——普通数组篇:缺失的第一个正数
算法·leetcode·哈希算法