每日一题:LeetCode-76. 最小覆盖子串

刷题使我快乐,满脸开心.jpg
来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题目
给你一个字符串 s
、一个字符串 t
。返回 s
中涵盖 t
所有字符的最小子串。如果 s
中不存在涵盖 t
所有字符的子串,则返回空字符串 ""
。
注意:
对于
t
中重复字符,我们寻找的子字符串中该字符数量必须不少于t
中该字符数量。如果
s
中存在这样的子串,我们保证它是唯一的答案。
示例 1:
示例 2:
示例 3:
提示:
m == s.length
n == t.length
1 <= m, n <= 105
s
和t
由英文字母组成
进阶:你能设计一个在
o(m+n)
时间内解决此问题的算法吗?
思路
最开始看到题目,想的就是哈希表存储字符计数
,然后每次增加一个字符就看下是否满足,那么刚刚满足所有字符时就是最小覆盖子串
了,不过当看到第一条注意以及示例时,意识到如果是字符存在重复的话,那么就有可能刚刚满足时并不是最小的覆盖子串
。
但是,基于思路不能轻易浪费的念头,继续顺着这个思路思考下:
如果此时
覆盖子串
并不是最短的,如果收缩?如果需要收缩,右边界也就是遍历方向,如果遍历方向上满足了
覆盖子串
需求时,会立即触发判断,所以右边界并不需要收缩,反证法易得结论左边界如果收缩?
对于如下例子来说,刚刚找到第一个
覆盖子串
时,其实可以让L
指针继续右移到c
处,此时才是最小覆盖子串
,所以左边界收缩的特点就是找到覆盖子串
后,逐步右移L
,并同步的修改覆盖子串
的字符计数
信息,只要继续满足那就有可能会更新最小覆盖子串
的长度,同时记录最小覆盖子串
的位置坐标信息就好了

能否简化操作。比如字符串中常见的,找到一个
最小覆盖子串
后,移动L
到R
位置,减少L
的遍历次数?不可,因为在移动过程中,可能错过
覆盖子串
,比如上图中,如果R
右移两个位置后,其实L
在第一个b
的位置才是最小覆盖子串
,但是如果移动L
到R
位置,将会错过此结果
至此,上代码,细节在备注里了~
代码
版权声明: 本文为 InfoQ 作者【半亩房顶】的原创文章。
原文链接:【http://xie.infoq.cn/article/548e8bb226300fbfe9fcdda2d】。文章转载请联系作者。
评论