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

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

  • 不重新扫描窗口

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

  • 判断窗口是否满足条件用 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]--

  • 如果 need[c] > 0,说明这个字符正是我们需要的

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

  • 如果 need[c] <= 0,说明窗口中多出来了

    → 不影响 count


左指针移除一个字符 lc

need[lc]++

  • 如果 need[lc] > 0,说明刚移走的是一个必须字符

    → 再次缺失了 → count++

  • 如果 need[lc] <= 0,说明移走的是冗余字符

    → 不影响覆盖性

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

相关推荐
仰泳的熊猫3 分钟前
题目2570:蓝桥杯2020年第十一届省赛真题-成绩分析
数据结构·c++·算法·蓝桥杯
无极低码3 小时前
ecGlypher新手安装分步指南(标准化流程)
人工智能·算法·自然语言处理·大模型·rag
软件算法开发4 小时前
基于海象优化算法的LSTM网络模型(WOA-LSTM)的一维时间序列预测matlab仿真
算法·matlab·lstm·一维时间序列预测·woa-lstm·海象优化
罗超驿4 小时前
独立实现双向链表_LinkedList
java·数据结构·链表·linkedlist
superior tigre4 小时前
22 括号生成
算法·深度优先
努力也学不会java5 小时前
【缓存算法】一篇文章带你彻底搞懂面试高频题LRU/LFU
java·数据结构·人工智能·算法·缓存·面试
旖-旎6 小时前
二分查找(x的平方根)(4)
c++·算法·二分查找·力扣·双指针
ECT-OS-JiuHuaShan6 小时前
朱梁万有递归元定理,重构《易经》
算法·重构
智者知已应修善业7 小时前
【51单片机独立按键控制数码管移动反向,2片74CH573/74CH273段和位,按键按下保持原状态】2023-3-25
经验分享·笔记·单片机·嵌入式硬件·算法·51单片机