力扣 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,保证逻辑正确。
相关推荐
aaaameliaaa1 天前
字符函数和字符串函数
c语言·笔记·算法
城管不管1 天前
ReAct、Plan-and-Execute、Reflection 三大智能 Agent 范式核心区别
java·人工智能·算法·spring·ai·动态规划
月疯1 天前
二分法算法(水平等分图形面积)
算法
豆瓣鸡1 天前
算法日记 - Day3
java·开发语言·算法
白白白小纯1 天前
算法篇—反转链表
c语言·数据结构·算法·leetcode
Achou.Wang1 天前
深入理解go语言-第5章 并发编程——Go的灵魂
大数据·算法·golang
The Chosen One9851 天前
高进度算法模板速记(待完善)
java·前端·算法
小王C语言1 天前
【7. 实现登录注册模块】:实现会话管理、注册/登录/退出 API
网络·c++
圣保罗的大教堂1 天前
leetcode 3517. 最小回文排列 I 中等
leetcode
土豆.exe1 天前
Fastjson2 2.0.53 哈希碰撞 RCE:从原理到三种打法
算法·哈希算法