首页 > 其他分享 >76. 最小覆盖子串(难)

76. 最小覆盖子串(难)

时间:2024-03-11 20:55:21浏览次数:27  
标签:子串 字符 窗口 最小 76 字符串 need 滑动

目录

题目

  • 给你一个字符串 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 的子串中,
因此没有符合条件的子字符串,返回空字符串。

滑动窗口

class Solution:
    def minWindow(self, s: str, t: str) -> str:
        need = {}    # 存储字符串 t 中各个字符的需求量
        window = {}  # 存储滑动窗口中各个字符的出现次数
        for c in t:#遍历字符串t
            need.setdefault(c, 0)#访问不存在的键时自动创建并将值设置为 0
            need[c] += 1  # 统计字符串 t 中各个字符的需求量

        left = 0    # 滑动窗口的左指针
        right = 0   # 滑动窗口的右指针
        valid = 0   # 记录满足需求的字符数
        start = 0   # 最小覆盖子串的起始位置
        length = float('inf')   # 最小覆盖子串的长度

        while right < len(s):
            c = s[right]    # 当前字符
            right += 1      # 右指针右移

            if c in need:#当前字符是目标字符中的
                window.setdefault(c, 0)#访问不存在的键时自动创建并将值设置为 0
                window[c] += 1  # 更新滑动窗口中当前字符的出现次数
                if window[c] == need[c]:
                    valid += 1  # 如果滑动窗口中当前字符的出现次数达到需求量,增加满足需求的字符数

            while valid == len(need):#每个字符的次数都达到了要求
                if right - left < length:#当前窗口的长度是否小于已记录的最小覆盖子串长度 length。
                    start = left#如果是,则更新最小覆盖子串的起始位置和长度
                    length = right - left  # 更新最小覆盖子串的起始位置和长度

                d = s[left]   # 将要移出窗口的字符
                left += 1     # 左指针右移

                if d in need:#当前字符是目标字符中的
                    if window[d] == need[d]:#如果滑动窗口中当前字符等于目标字符的值
                        valid -= 1   # 如果移出窗口的字符导致窗口不再满足需求,则减少满足需求的字符数
                    window[d] -= 1  # 更新滑动窗口中移出字符的出现次数

        return "" if length == float('inf') else s[start:start + length]  # 返回最小覆盖子串

标签:子串,字符,窗口,最小,76,字符串,need,滑动
From: https://www.cnblogs.com/lushuang55/p/18067008

相关文章

  • 746. 使用最小花费爬楼梯c
    intmin(inti,intj){if(i<j)returni;returnj;}intminCostClimbingStairs(int*cost,intcostSize){int*dp=(int*)malloc(sizeof(int)*(costSize+3));dp[0]=0;dp[1]=0;for(inti=2;i<=costSize;i++){dp[i]=min(dp[i-......
  • 1.1.3.4 最小割之建图实战、费用流基本概念
    1.1.3.4最小割之建图实战、费用流基本概念最小割之建图实战381.有线电视网络Problem给定一张n个点m条边的无向图,求最少去掉多少个点,可以使图不连通。如果不管去掉多少个点,都无法使原图不连通,则直接返回n。Solution最小割模型的通用分析方式:通过原图构造一个流网络......
  • POJ--3258 River Hopscotch(二分搜索/最大化最小值)
    记录10:232023-3-11http://poj.org/problem?id=3259二分法查找最大的可能解,检查x是否符合条件(当前这个位置上的值-前上一个选取位置的值>=x)注意的点:使用了[begin,end)的左闭右开区间,所以结果要begin-1,end要从L+1开始算点击查看代码intL,N,M;introcks[5......
  • 视野修炼-技术周刊第76期 | Rolldown 开源
    欢迎来到第76期的【视野修炼-技术周刊】,下面是本期的精选内容简介......
  • 376. 摆动序列c
    动态规划yyds!虽然写不出来TTintmax(inti,intj){if(i>j)returni;returnj;}intwiggleMaxLength(int*nums,intnumsSize){intdp[1000][2]={0};//dp[i][j]表示到0-i为止的最大子序列,1表示最后是上升,0表示最后是下降if(numsSize==1)return1;......
  • CF763E Timofey and our friends animals
    使用回滚莫队可以有效降低思维含量。对于回滚莫队和可撤销并查集,本文不再赘述。假设当前询问是\([L,R]\),目前加入了\([l,r]\)的所有点和边。将\(r\)增加\(1\)时,连边\((r+1,v\in[l,r])\)。然后需要处理左边的散块。对于所有零散的\(l\),连边\((l,v\in[L,R])\)。上述两......
  • Sqlite3之左子串,右子串,中间串subStr函数(14)
    右子串  subStr('一二三四五',-4)selectsubStr('一二三四五',-4) 左子串  substr('一二三四五',1,3) 中串,比如取出三四  selectsubStr('一二三四五',3,2) ......
  • 7-11 最长对称子串
    7-11最长对称子串分数15作者陈越单位浙江大学对给定的字符串,本题要求你输出最长对称子串的长度。例如,给定IsPAT&TAPsymmetric?,最长对称子串为sPAT&TAPs,于是你应该输出11。输入格式:输入在一行中给出长度不超过1000的非空字符串。输出格式:在一行中输出最长对称子串......
  • 153. 寻找旋转排序数组中的最小值(中)
    目录题目题解:二分题目已知一个长度为n的数组,预先按照升序排列,经由1到n次旋转后,得到输入数组。例如,原数组nums=[0,1,2,4,5,6,7]在变化后可能得到:若旋转4次,则可以得到[4,5,6,7,0,1,2]若旋转7次,则可以得到[0,1,2,4,5,6,7]注意,数组[a[0],a[1],a[2],...,a......
  • 杭电OJ 2028求n个数的最小公倍数
    LowestCommonMultiplePlus首先,求a、b两个数的最小公倍数很简单,只要先求出其最大公约数,再\(a*b/GCD(a,b)\)。那么求n个数的最小公倍数,思路也是一样的。但是OJ判题一直WA,查了一下别的博客,发现错误的原因是在求公倍数的过程中要先除再乘,防止溢出,即\(a/GCD(a,b)*b\)以及要......