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;
    }
}
相关推荐
wen__xvn1 天前
代码随想录算法训练营DAY1第一章 数组part01
数据结构·算法·leetcode
在风中的意志1 天前
[数据库SQL] [leetcode-175] 175. 组合两个表
数据库·sql·leetcode
圣保罗的大教堂1 天前
leetcode 1970. 你能穿过矩阵的最后一天 困难
leetcode
造夢先森1 天前
常见数据结构及算法
数据结构·算法·leetcode·贪心算法·动态规划
iAkuya1 天前
(leetcode)力扣100 29删除链表的倒数第 N 个结点(双指针)
算法·leetcode·链表
Binky6781 天前
力扣--贪心(2)+动规(1)
算法·leetcode·职场和发展
长安er1 天前
LeetCode215/347/295 堆相关理论与题目
java·数据结构·算法·leetcode·
元亓亓亓1 天前
LeetCode热题100--62. 不同路径--中等
算法·leetcode·职场和发展
小白菜又菜1 天前
Leetcode 1925. Count Square Sum Triples
算法·leetcode
POLITE32 天前
Leetcode 41.缺失的第一个正数 JavaScript (Day 7)
javascript·算法·leetcode