最小覆盖字串(滑动窗口)

该题使用滑动窗口的增量统计机制,

  • 不重新扫描窗口

  • 每次右边加一个字符、左边减一个字符,就更新一次计数

  • 判断窗口是否满足条件用 O(1)

一开始我使用虽然也是滑动窗口,但是类似于暴力求解,时间复杂度为O(N^2):因为每次左指针每滑动一次时,检查是否满足覆盖条件仍然是O(N),所以整体下来就是O(N^2)。

cpp 复制代码
class Solution {
public:
    
    bool IsCover(string& s, int left, int right,unordered_map<char,int> charnum){
        for(int i =left;i<=right;i++){
            auto it=charnum.find(s[i]);
            if(it!=charnum.end()){
                if(charnum[s[i]]!=0) charnum[s[i]]--;
                if(charnum[s[i]]==0) charnum.erase(it);
            }
        }
        return charnum.empty();
    }

    string minWindow(string s, string t) {
        unordered_map<char,int> charnum;
        for(auto e: t) charnum[e]++;
        int left=0; int right=0; int flag=0; int min_left=0; int min_right=0; int min=100000; int cur;
        while(left<=right && right<s.size()){
            if(IsCover(s,left,right,charnum)){
                flag=1; cur=right-left+1; 
                if(cur<min){min_left=left; min_right=right; min=cur;}
                left++;
            }
            else right++;
        }
        
        if(flag==0) return "";
        else{
            string s1(s.begin()+min_left,s.begin()+min_right+1);
            return s1;
        }
    }
};

要使整体时间复杂度达到 O(N) ,必须采用滑动窗口的"增量统计"方式。核心思想是维护一个 count,表示当前窗口中还缺多少个字符才能完全覆盖字符串 t。

右指针扩张窗口时

  • 当 s[r] 是 t 中需要的字符(即哈希表 need[s[r]] > 0)时:

    • 说明我们弥补了一个缺失字符 → count--
  • 不论 need[s[r]] 是否大于 0,我们都执行 need[s[r]]--,

    这是为了在窗口内部维持正确的剩余需求。

当 count == 0 时

说明当前窗口已经包含 t 需要的全部字符,可以开始尝试收缩左指针。

左指针收缩窗口时

  • 在收缩前,先将 need[s[l]]++

  • 如果 need[s[l]] 增加后 大于 0 ,表示窗口因移除 s[l] 而缺少了该字符

    • → count++(窗口不再满足覆盖条件)

随后继续右移右指针,继续扩大窗口。

核心:need 是一个"差值计数器"

把 need 看成:

窗口中"缺少多少"这个字符(正数 = 缺,负数 = 多)

因此,随着窗口移动:

右指针进来一个字符 c

need[c]--

  • 如果 needc > 0,说明这个字符正是我们需要的

    → count--,表示距离满足目标更近了

  • 如果 needc <= 0,说明窗口中多出来了

    → 不影响 count


左指针移除一个字符 lc

need[lc]++

  • 如果 needlc > 0,说明刚移走的是一个必须字符

    → 再次缺失了 → count++

  • 如果 needlc <= 0,说明移走的是冗余字符

    → 不影响覆盖性

通过这种右 pointer 扩张、左 pointer 收缩的方式,我们可以保证每个字符最多被访问两次,因此整体时间复杂度为 O(N)。

相关推荐
小蒋观天下3 分钟前
【安防AI工程实战二】AI摄像头帧率抖动根治:ISP曝光时序与AI推理时序冲突深度定位
人工智能·深度学习·算法·安全·机器学习·ai大模型
云和数据.ChenGuang14 分钟前
trace 是RAG检索链路的**全链路追踪日志对象
人工智能·深度学习·算法·排序算法
Evand J17 分钟前
【PMSM例程6】永磁同步电机(PMSM)基于增广EKF的d-q轴电感分阶段辨识算法|电机参数估计与误差分析
算法·matlab·电机·ekf
垆边人似月.18 分钟前
华为题:最多可以参加的会议数目
数据结构·c++·算法
Tongzhi202618 分钟前
2026 年考勤行业趋势:考勤正在从“打卡工具“变成“人力成本中枢“
大数据·数据结构·数据仓库·科技·数据库开发
Matlab程序猿21 分钟前
【MATLAB源码-第460期】基于matlab的OTFS通信系统SLM峰均比抑制及非线性功率放大器失真与误码性能仿真
开发语言·算法·matlab·slm·otfs
xiangyun6122 分钟前
C++ list 模拟实现(一):手撕双向链表,从节点到迭代器
数据库·c++·算法·链表·stl·list
码爸9 小时前
线性回归算法
算法·机器学习·线性回归
Coder-magician9 小时前
《代码随想录》刷题打卡day51:图论-part09(dijistra堆优化,Bellman_ford算法)
算法·图论
Nil20810 小时前
leetcode 763划分字母区间
算法·leetcode·职场和发展