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;
    }
}
相关推荐
文丑颜不良啊12 小时前
LeetCode1661~1680题目解析
java·leetcode
文丑颜不良啊21 小时前
LeetCode1721~1740题目解析
java·leetcode
文丑颜不良啊21 小时前
LeetCode1681~1700题目解析
java·leetcode
开开心心就好1 天前
网页图片批量下载工具,输入链接就保存
服务器·算法·leetcode·支持向量机·pdf·ocr·1024程序员节
圣保罗的大教堂1 天前
leetcode 462. 最小操作次数使数组元素相等 II 中等
leetcode
Navigator_Z1 天前
LeetCode //C - 1313. Decompress Run-Length Encoded List
c语言·算法·leetcode
Nuanyt1 天前
LeetCode Hot 100 链表专题(四)· 3 题(Java)
java·算法·leetcode·链表·双指针
圣保罗的大教堂2 天前
leetcode 453. 最小操作次数使数组元素相等 中等
leetcode
Tisfy2 天前
LeetCode 0453.最小操作次数使数组元素相等:两次遍历(反向思维)
算法·leetcode·题解·遍历·反向思维
君万2 天前
【LeetCode每日一题】回溯:46. 全排列 78. 子集 39. 组合总和
算法·leetcode·go