力扣 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,保证逻辑正确。
相关推荐
叠层归一研究院14 分钟前
基于极限自指的叠层归一宇宙结构理论——无元外部封闭系统的内生区分模型
人工智能·经验分享·算法·agi
Selvaggia1 小时前
Diffusion Model 的基本原理与模型架构
算法
汉克老师2 小时前
CSP-J 2026 初赛试题解析(第一部分:选择题(8-15))精讲
c++·csp-j·小学生·学c++编程
wabs6663 小时前
关于二叉树【力扣572.另一棵树的子树的思考】
数据结构·c++·算法·leetcode·二叉树
hanlin033 小时前
刷题笔记:力扣第41题-缺失的第一个正数
笔记·算法·leetcode
shehuiyuelaiyuehao3 小时前
算法50,分治归并,数组中的逆序对
java·算法
风合星语4 小时前
2026 ROS 2 Lyrical C++ 入门(五):Action 实战——任务反馈、取消与超时处理
c++·机器人·ros2·异步编程·lyrical
阳明山水4 小时前
校准分位数驱动智能库存决策
人工智能·深度学习·算法·机器学习·架构
91刘仁德4 小时前
C++ 继承和多态 设计模式
c语言·c++·笔记
库玛西5 小时前
哈夫曼树与前缀编码:数据压缩的贪心核心
c语言·c++·笔记·考研