Title

给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。

示例:

输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”

说明:

  • 如果 S 中不存这样的子串,则返回空字符串 “”。
  • 如果 S 中存在这样的子串,我们保证它是唯一的答案。

Analysis

滑动窗口

要求我们返回字符串S中包含字符串T的全部字符的最小窗口。

在滑动窗口类型的问题中都会有两个指针,一个用于延伸现有窗口的right指针,一个用于收缩窗口的left指针。

在任意时刻,只有一个指针运动,而另一个指针保持静止。

我们在S上滑动窗口,通过移动right指针不断扩张窗口,当包含T全部所需字符后,如果能收缩,就收缩窗口直到得到最小窗口。

如何判断当前的窗口包含所有T所需的字符?

我们可以用一个哈希表表示T中所有的字符以及它们的个数,用一个哈希表动态维护窗口中所有的字符以及它们的个数,如果这个动态表中包含T的哈希表中的所有字符,并且对应的个数都不小于T的哈希表中各个字符的个数,那么当前窗口就是一个可行窗口。

注意:这里 tt 中可能出现重复的字符,所以我们要记录字符的个数。

复杂度分析:

  • 时间复杂度:最坏情况下左右指针对S的每个元素各遍历一遍,哈希表中对S中的每个元素各插入、删除一次,对T中的元素各插入一次。每次检查是够可行会遍历整个T的哈希表,哈希表的大小与字符集的大小有关,设字符集的大小为C,则渐进时间复杂度为O(C⋅∣s∣+∣t∣)。
  • 空间复杂度:这里用了两张哈希表作为辅助空间,每张哈希表最多不存放超过字符集大小的键值对,设字符集的大小为C,则渐进空间复杂度为O©。

Code

def minWindow(self, s: str, t: str) -> str:import collectionsn, left, ans, cnt = 0, 0, '', collections.Counter(t)for right, ch in enumerate(s):if ch not in cnt:continue# 统计当前字符,判断是否已经达到数量要求cnt[ch] -= 1if cnt[ch] == 0:n += 1# 如果当前在left的字符没有必要,可以右移左指针while s[left] not in cnt or cnt[s[left]] < 0:if s[left] in cnt:cnt[s[left]] += 1left += 1if n == len(cnt):if not ans or len(ans) > right - left + 1:ans = s[left: right + 1]return ans

如何优化?

如果S = XX⋯XABCXXXX,T = ABC,那么显然[XX⋯XABC]是第一个得到的可行区间,得到这个可行区间后,我们按照收缩窗口的原则更新左边界,得到最小区间。

在这个过程中其实做了很多无用功,更新右边界的时候延伸进了很多无用的X,更新左边界的时候又收缩了这些无用的X,而这些无用的操作只是为了得到短短的ABC。

其实在S中,只需要关心T中出现的字符,可以先对S进行预处理,扔掉那些T中没有出现的字符,然后再做滑动窗口。

例如,对于XXABXXC的情况,在统计长度的时候可以扔掉前两个X,但是不扔掉中间的X。

76. 最小覆盖子串相关推荐

  1. Leetcode 76最小覆盖子串77组合78子集

    新人公众号(求支持):bigsai 专注于Java.数据结构与算法,一起进大厂不迷路! 算法文章题解全部收录在github仓库bigsai-algorithm,求star! 关注回复进群即可加入力扣打 ...

  2. 【LeetCode】【HOT】76. 最小覆盖子串(滑动窗口)

    [LeetCode][HOT]76. 最小覆盖子串 文章目录 [LeetCode][HOT]76. 最小覆盖子串 package hot;public class Solution76 {public ...

  3. java最小子串覆盖_LeetCode 76. 最小覆盖子串

    LeetCode 76. 最小覆盖子串 题目 给你一个字符串 S.一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串. 示例: 输入: S = "ADOBECODEBAN ...

  4. LeetCode 76. 最小覆盖子串 (滑动窗口哈希表)

    LeetCode 76. 最小覆盖子串 思路: 准备一个map1记录字符串t(字符, 字符个数) 准备一个map2记录在s的窗口中所包含的t串字符(字符,字符个数) 左端点收缩条件:窗口内已经覆盖了t ...

  5. LeetCode高频题76. 最小覆盖子串:欠账还债还款问题,子串考虑i开头的情况所有答案更新一波

    LeetCode高频题76. 最小覆盖子串:欠账还债还款问题,子串考虑i开头的情况所有答案更新一波 提示:本题是系列LeetCode的150道高频题,你未来遇到的互联网大厂的笔试和面试考题,基本都是从 ...

  6. 72.编辑距离105.前序中序遍历序列构造二叉树151.翻转字符串里的单词104.二叉树的最大深度76.最小覆盖子串110.平衡二叉树31.下一个排列

    72.编辑距离 给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数 .你可以对一个单词进行如下三种操作:插入一个字符,删除一个字符,替换一个字符. ...

  7. 【LeetCode】76. 最小覆盖子串 (Java代码)

    [LeetCode]76. 最小覆盖子串 (Java代码) 来源:力扣(LeetCode) 题目链接:https://leetcode.cn/problems/minimum-window-subst ...

  8. LeetCode - 76 最小覆盖子串

    目录 题目来源 题目描述 示例 提示 题目解析 算法源码 题目来源 76. 最小覆盖子串 - 力扣(LeetCode) 题目描述 给你一个字符串 s .一个字符串 t .返回 s 中涵盖 t 所有字符 ...

  9. 76. 最小覆盖子串(滑动窗口)

    给你一个字符串 s .一个字符串 t .返回 s 中涵盖 t 所有字符的最小子串.如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" . 注意: 对于 t 中重复字符 ...

最新文章

  1. mysql锁总结知乎_Mysql悲观锁乐观锁区别与使用场景
  2. 记者因报道大厂负面遭遇死亡威胁,幕后黑手被判入狱18个月
  3. [SDOI2009]HH去散步(矩阵)
  4. 台式计算机键盘配置及价格,最新台式电脑组装配置单及价格【图文】
  5. 类图的使用 c# 1613918428
  6. ICML(2020)对抗学习论文汇总
  7. spring-beanFactory二
  8. GeoTiff及GDAL切图(java)
  9. 携号转网不会有多大影响
  10. [含论文+源码等]javaweb银行柜员业务绩效考核系统
  11. QTP教程02 - 对象库及原理透析
  12. 地理加权回归的学习(地理加权回归用来量化空间异质性)
  13. php 微信公号授权登入,laravel实现微信公众号授权登录实战
  14. 便携式三星mysql_三星折叠手机终于来了!9 月 18 日正式发售
  15. 1894 Beckham’s Freekick
  16. 如何在Windows和Mac下挂载EFI分区
  17. RSA中的中国剩余定理(CRT)和多素数(multi-prime)
  18. 异同移动平均线原理(macd)
  19. cesium--画一个椭球
  20. 双十二投影仪推荐 三分钟告诉你怎么挑选到称心如意的投影仪

热门文章

  1. $Django 多表操作(增删改查,基于双下划线,对象的查询) 在Python脚本中调用Django环境...
  2. NOIP 2013 day1
  3. day_work_02
  4. 生成Geometry
  5. libevent(1)
  6. 戏说模式-追MM与设计模式 (转载)
  7. for循环 php 增加数组维数_PHP数组在循环中创建多维数组
  8. java方面的文献综述怎么写_如何写文献综述?
  9. axure类型app项目rp文件_Python编程快速上手实践项目--选择性拷贝指定类型文件到目的目录...
  10. Java黑皮书课后题第2章:*2.8(当前时间)程序清单2-7给出了显示当前格林尼治时间的程序。修改这个程序,提示用户输入相对于GMT的时区偏移量,显示在这个特定时区的时间