滑动窗口之76.最小覆盖子串

本文介绍了如何使用滑动窗口技巧解决LeetCode上的MinimumWindowSubstring问题,通过Python实现,讲述了如何利用字典跟踪目标字符需求并维护窗口状态。关键在于理解窗口操作和元素计数的方法,以找到包含字符串t所有字符的最小子串。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

76. Minimum Window Substring (最小覆盖子串 Hard)

题目描述:

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

注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。

输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"

思路记录:

利用滑动窗口,设置两个指针分别指向滑动窗口的首尾位置。
左右指针分别用来缩小和扩展窗口,左指针初始为0,右指针从起始位置开始遍历字符串。
当滑动窗口中包含了所有的t中的目标字符,j停止扩展,开始向右移动i,收缩窗口,找到包含t中所有字符的最小滑动窗口,此时j-i+1为窗口长度;继续将i向右移动一位,然后重复上述步骤,最后长度的最小值就是要求的结果。

判断滑动窗口是否包含了t的所有元素?
通过字典need来表示滑动窗口中还需要的各元素的数量,只要某个元素包含在滑动窗口中,就在need中对应的元素的数值-1,移除元素时,need中对应数值加1;

初始时need中的元素为t中每个元素,且对应的需要数量全为1.

如果是负数则代表这个元素是多余的,数量为0时表示刚刚好。
如果当need中所有元素的数量都小于等于0时,表示当前滑动窗口不再需要任何元素。

再额外设置一个neednum,代表滑动窗口中所需元素的总数,当遍历到在t中的一个元素c时,need[c]-=1,neednum-=1,这样当neednum==0时,即滑动窗口中包含了t的所有元素。

注:只有当need[c]>0,neednum才减1。防止添加重复的t中的元素造成减1

代码:

from collections import defaultdict
class Solution:
    def minWindow(self, s: str, t: str) -> str:
        need = defaultdict(int)
        for c in t:
            need[c] += 1
        i = 0
        neednum = len(t)
        
        res=(0,float('inf'))  #记录起点终点
        for j,c in enumerate(s):
            if need[c] > 0:
                neednum -= 1
            need[c] -= 1   #遍历到每个元素都需要减1
            if neednum == 0:
                while True:
                    c = s[i]   #从i指向的位置开始
                    if need[c] == 0:  #表明当前元素为第一个处于t中的元素
                        break
                    need[c] += 1
                    i += 1   #i右移
                    
                    if j - i < res[1] - res[0]:
                        res = (i, j)
                        
                    need[s[i]] += 1    #i所处的位置是需要的第一个位置的元素
                    neednum += 1
                    i += 1     #i向后移动一位
                
            return "" if res[1]>len(s) else s[res[0]:res[1]+1]

参考:
力扣题解作者:https://leetcode-cn.com/u/mcdull0921/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值