力扣 76. 最小覆盖子串

最小覆盖子串

https://leetcode.cn/problems/minimum-window-substring/description/

问题描述

给定字符串 st,在 s 中找出包含 t 所有字符(包括重复个数)的最短连续子串,返回该子串。若不存在,返回空字符串。


解题思路

使用滑动窗口(双指针)算法,时间复杂度 O(m + n),空间复杂度 O(字符集大小)。

  1. 统计需求 :用哈希表 need 记录 t 中每个字符需要的个数,并用 required 记录不同字符的种类数。
  2. 滑动窗口 :维护左右指针 lr,初始时都指向 0。
  3. 扩展右指针 :每次移动 r 扩大窗口,将当前字符加入窗口计数 window。若该字符在 need 中且 window[c] == need[c],则说明该字符的需求已满足,ans 加 1。
  4. 收缩左指针 :当 ans == required 时,说明当前窗口已覆盖 t,尝试移动 l 缩小窗口,同时更新最小长度和起始位置。若移动后窗口不再满足,则 ans 减 1。
  5. 重复 :直到 r 遍历完整个 s
  6. 结果:根据记录的最小起始位置和长度返回子串。

代码实现(C++)

cpp 复制代码
class Solution {
public:
    string minWindow(string s, string t) {
        if(s.size()<t.size()) return "";
        unordered_map<char,int> need,window;
        for(char c:t) need[c]++;
        int required =need.size();
        int l = 0,r =0;
        int ans=0;
        int i=0,len=INT_MAX;
        while(r<s.size()){
            char c=s[r];
            r++;
            if(need.count(c)){//当前字符在t中
                window[c]++;
                if(window[c]==need[c]) ans++;
            }
            while(ans==required){//当前已满足子串包含t中的每一个字符
                if(r-l<len){//如果当前子串更优
                    i=l;
                    len=r-l;
                }
                char d=s[l];
                l++;
                if(need.count(d)){
                    if(window[d]==need[d]) ans--;
                    window[d]--;
                }
            }
        }
        return len == INT_MAX ? "" : s.substr(i, len);
    }
};

复杂度分析

  • 时间复杂度:O(m + n),其中 m 和 n 分别为 s 和 t 的长度。每个字符最多被左右指针各访问一次。
  • 空间复杂度:O(字符集大小),由于字符为英文字母,最多 52 个,可视为常数。若使用哈希表,则与字符种类数相关。

关键点

  • 使用 need 记录需求,window 记录当前窗口的字符计数。
  • ans 记录已满足需求的字符种类数,避免每次遍历整个 need
  • 收缩窗口时,只有当 window[d] == need[d] 时才减少 ans,保证逻辑正确。
相关推荐
Buke..5 分钟前
【APP 逆向】哔哩哔哩 sign 参数逆向(下):OLLVM 混淆还原 sign 算法
java·javascript·爬虫·python·算法
闲研随记37 分钟前
【文献阅读 ICLR 2026】RL算法:DECS
算法·llm·强化学习·iclr·rl
量化小c1 小时前
一行代码查 BTCUSDT 和 AAPL 最新价?QuantDash 统一多市场实时行情接口实战
后端·算法·github
沙盘客1 小时前
AFSIM 官方案例库全景与解读方法论
c++·经验分享·后端
机器人梦想家1 小时前
具身机器人视觉服务的异步回调与并发控制
数据库·算法·机器人
_wxd6662 小时前
STL-stack与queue与priority_queue(容器适配器)
c++
我命由我123452 小时前
人脸识别 - 人脸识别选帧
java·人工智能·python·算法·安全·java-ee·人脸识别
时针滴滴答啊2 小时前
最大子数组和
算法·leetcode·职场和发展
zh路西法3 小时前
【玩转VLA具身智能机械臂】(二):MoveIt2 运动规划——架构、配置与 C++ 上手
c++·机械臂·路径规划·vla·planner·moveit2
五月底_3 小时前
LIS算法
python·算法·最长子序列