前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode 76. 最小覆盖子串

LeetCode 76. 最小覆盖子串

原创
作者头像
freesan44
修改2021-10-25 10:45:49
4190
修改2021-10-25 10:45:49
举报
文章被收录于专栏:freesan44

题目地址(76. 最小覆盖子串)

https://leetcode-cn.com/problems/minimum-window-substring/

题目描述

代码语言:txt
复制
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。

 

注意:

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

 

示例 1:

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


示例 2:

输入:s = "a", t = "a"
输出:"a"


示例 3:

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

 

提示:

1 <= s.length, t.length <= 105
s 和 t 由英文字母组成

 

进阶:你能设计一个在 o(n) 时间内解决此问题的算法吗?

思路

滑动窗口,右边扩张,满足字符串遍历条件后,左边收缩,难点在于左边收缩的边界条件

代码

  • 语言支持:Python3

Python3 Code:

代码语言:txt
复制
class Solution:
    def minWindow(self, s: str, t: str) -> str:
        from collections import Counter
        length = len(s)
        left,right,match = 0, 0,0
        resLeft,resRight,minResLen = 0, 0,length+1
        tDict = Counter(t)
        while right < length:
            #先右边扩张
            # print(left, right, resLeft, resRight)
            # print([s[left:right+1]])
            rS = s[right]
            # print(rS,tDict)
            if rS in tDict:
                tDict[rS] -= 1
                if tDict[rS] >= 0:
                    match += 1
            #收缩条件
            while match == len(t):
                #判断是否最短子串长度
                if (right - left) < minResLen:
                    # print([s[left:right + 1]],resRight,resLeft, minResLen)
                    minResLen = min(minResLen,right-left)
                    resLeft,resRight = left,right
                #左边在收缩,直到mtath<len(t)
                if left <= right:
                    lS = s[left]
                    if lS in tDict:
                        tDict[lS] += 1
                        if tDict[lS] > 0:
                            match -= 1
                        # print(lS, tDict)
                    left += 1
            right += 1
        # print(left, right, resLeft, resRight)
        return s[resLeft:resRight+1] if minResLen != length+1 else ""

if __name__ == '__main__':
    s = "ADOBECODEBANC"
    t = "ABC"
    s = "a"
    t = "a"
    result = Solution().minWindow(s,t)
    print(result)

复杂度分析

令 n 为数组长度。

  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(n)$

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目地址(76. 最小覆盖子串)
  • 题目描述
  • 思路
  • 代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档