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

题目

给定两个字符串 sp,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

这道题沿用上一题的思路,我会这么做

cpp 复制代码
class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        unordered_map<string, vector<int>> mp;
        string p_p = p;
        sort(p_p.begin(), p_p.end());
        int i = 0, j = p.size();
        while (i + j <= s.size()) {
            string str = s.substr(i, j);
            sort(str.begin(), str.end());
            mp[str].emplace_back(i);
            i++;
        }
        return mp[p_p];
    }
};

代码是简洁了,思路也清晰,就是这个循环加上sort、substr这个时间开销太大了,导致最后运行超时

那么改如何优化呢

cpp 复制代码
class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        vector<int> ans;
        int n = s.size(), k = p.size();
        if(k > n) return ans; // p比s长,直接返回空

        vector<int> cntP(26,0);
        vector<int> cntS(26,0);

        // 统计p的字符频次
        for(char ch : p){
            cntP[ch - 'a']++;
        }

        // 先初始化第一个窗口 [0 , k‑1]
        for(int i = 0; i < k; i++){
            cntS[s[i] - 'a']++;
        }

        // 计算diff:频次不相等的字母总个数
        int diff = 0;
        for(int i = 0; i < 26; i++){
            if(cntS[i] != cntP[i]) diff++;
        }

        if(diff == 0){
            ans.emplace_back(0);
        }

        // 滑动窗口,窗口起点从1开始
        for(int l = 1; l <= n - k; l++){
            // 1.要移出窗口的字符:s[l‑1]
            char out = s[l - 1];
            int idxOut = out - 'a';
            // 移出之前,如果两边不等,移出之后有可能相等,diff变化
            if(cntS[idxOut] == cntP[idxOut]) diff++; //相等的话就要加,说明改字符后不匹配的
            cntS[idxOut]--; //正常移动窗口提走字母
            if(cntS[idxOut] == cntP[idxOut]) diff--; //如果相减后匹配,则说明diff可以减一

            // 2.新进入窗口的字符:s[l + k -1]
            char in = s[l + k -1];
            int idxIn = in - 'a';
            if(cntS[idxIn] == cntP[idxIn]) diff++;
            cntS[idxIn]++;
            if(cntS[idxIn] == cntP[idxIn]) diff--;

            // diff为0,窗口匹配
            if(diff == 0){
                ans.emplace_back(l);
            }
        }
        return ans;
    }
};

移动窗口不熟悉,多想想

相关推荐
圣保罗的大教堂1 小时前
leetcode 1140. 石子游戏 II 中等
leetcode
Nil2081 小时前
leetcode 22括号生成
算法·leetcode·深度优先
Navigator_Z1 小时前
LeetCode //C - 1237. Find Positive Integer Solution for a Given Equation
c语言·算法·leetcode
码少女1 小时前
数据结构——堆排序
数据结构
政企项目老覃12 小时前
大模型幻觉治理与自动评测:金融风控场景的落地实践
人工智能·算法·机器学习
淡海水13 小时前
08-03-不可变-ImmutableDictionary-TKey-TValue-与ImmutableHashSet-T-持久化哈希树
数据结构·算法·c#·哈希算法·dictionary·immutable
hansang_IR13 小时前
【题解】[APIO2023] 赛博乐园 / cyberland
c++·算法·图论
洛阳纸贵13 小时前
MATLAB-matlab基础知识
学习·算法·matlab