Leetcode刷题详解——最小覆盖子串

1. 题目链接:76. 最小覆盖子串

2. 题目描述:

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 ""

注意:

  • 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
  • 如果 s 中存在这样的子串,我们保证它是唯一的答案。

示例 1:

复制代码
输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
解释:最小覆盖子串 "BANC" 包含来自字符串 t 的 'A'、'B' 和 'C'。

示例 2:

复制代码
输入:s = "a", t = "a"
输出:"a"
解释:整个字符串 s 是最小覆盖子串。

示例 3:

复制代码
输入: s = "a", t = "aa"
输出: ""
解释: t 中两个字符 'a' 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。

提示:

  • m == s.length
  • n == t.length
  • 1 <= m, n <= 105
  • st 由英文字母组成

3. 解法(滑动窗口+哈希表)

3.1 算法思路:

  1. 创建两个哈希表,其中一个将目标串的信息统计起来,另一个哈希表动态的维护窗口内字符串的信息
  2. 当动态哈希表中包含目标串中所有的字符,并且对应的个数都不小于目标串的哈希表中各字符的个数,那么当前的窗口就是一种可行的方案

3.2 算法流程:

  1. 定义两个辅助数组:hash1hash2hash1用于统计字符串t中每个字符的频次,hash2用于统计窗口内每个字符的频次。

  2. 使用变量kinds统计字符串t中有效字符的种类数。遍历字符串t,若hash1[ch]++ == 0,则表示该字符是新字符,将kinds加1。

  3. 初始化变量minlen为最大整数,表示最小窗口的长度,begin为-1,表示最小窗口的起始位置。

  4. 使用双指针leftright,遍历字符串s。对于每个字符in=s[right],将其在hash2中的频次加1。

  5. 如果hash2[in] == hash1[in],说明窗口内的某个字符in已经达到了所需的频次,将count加1。

  6. 如果count等于kinds,说明窗口内包含了字符串t中的所有有效字符。此时需要更新结果。

  7. 如果当前窗口的长度小于minlen,将minlen更新为当前窗口的长度,begin更新为当前窗口的起始位置。

  8. 将窗口左边界向右移动,即将字符s[left++]移出窗口。如果hash2[out] == hash1[out] - 1,说明窗口内的字符out频次减少后仍然满足要求,将count减1。

  9. 重复步骤4至8,直到right遍历完整个字符串s

  10. 最后判断begin是否仍然为-1,如果是则表示未找到满足要求的最小窗口子串,返回空字符串。否则,返回字符串s中起始位置为begin,长度为minlen的子串作为结果。

3.3 C++算法代码:

c++ 复制代码
class Solution {
public:
    string minWindow(string s, string t) {
        int hash1[128]={0};//统计字符串t中每个字符的频次
        int kinds=0;//统计有效字符有多少种
        for(auto ch:t)
            if(hash1[ch]++==0) kinds++;
        int hash2[128]={0};//统计窗口内每个字符的频次
        int minlen=INT_MAX,begin=-1;
        for(int left=0,right=0,count=0;right<s.size();right++)
        {
            char in=s[right];
            if(++hash2[in]==hash1[in]) count++;//进窗口+维护count
            while(count==kinds) //判断条件
            {
                 if(right-left+1<minlen)//更新结果
                 {
                     minlen=right-left+1;
                     begin=left;
                 }
                 char out=s[left++];
                 if(hash2[out]--==hash1[out]) count--;
            }
        }
        if(begin==-1) return "";
        else return s.substr(begin,minlen);
    }
};
相关推荐
天上路人2 小时前
AI神经网络降噪算法在语音通话产品中的应用优势与前景分析
深度学习·神经网络·算法·硬件架构·音视频·实时音视频
好吃的肘子2 小时前
MongoDB 应用实战
大数据·开发语言·数据库·算法·mongodb·全文检索
汉克老师2 小时前
GESP2025年3月认证C++二级( 第三部分编程题(1)等差矩阵)
c++·算法·矩阵·gesp二级·gesp2级
sz66cm2 小时前
算法基础 -- 小根堆构建的两种方式:上浮法与下沉法
数据结构·算法
独行soc2 小时前
2025年渗透测试面试题总结-阿里云[实习]阿里云安全-安全工程师(题目+回答)
linux·经验分享·安全·阿里云·面试·职场和发展·云计算
緈福的街口2 小时前
【leetcode】94. 二叉树的中序遍历
算法·leetcode
小刘要努力呀!3 小时前
嵌入式开发学习(第二阶段 C语言基础)
c语言·学习·算法
程序员小远3 小时前
UI自动化测试方案详解
自动化测试·软件测试·selenium·测试工具·ui·职场和发展·测试用例
野曙4 小时前
快速选择算法:优化大数据中的 Top-K 问题
大数据·数据结构·c++·算法·第k小·第k大
Codeking__4 小时前
”一维前缀和“算法原理及模板
数据结构·算法