目录
1、题目
给你一个字符串 s
、一个字符串t
。返回 s
中涵盖 t
所有字符的最小子串。如果 s
中不存在涵盖t
所有字符的子串,则返回空字符串 “” 。
注意: 如果s
中存在这样的子串,我们保证它是唯一的答案。
示例 1:
输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
示例 2:
输入:s = "a", t = "a"
输出:"a"
提示:
1 <= s.length, t.length <= 105
s
和t
由英文字母组成
进阶: 你能设计一个在
o
(
n
)
o(n)
o(n)时间内解决此问题的算法吗?
2、思路
(滑动窗口)
O
(
n
)
O(n)
O(n)
这道题要求我们返回字符串s
中包含字符串 t
的全部字符的最小窗口,我们利用滑动窗口的思想解决这个问题。因此我们需要两个哈希表,hs
哈希表维护的是s
字符串中滑动窗口中各个字符出现多少次,ht
哈希表维护的是t
字符串各个字符出现多少次。如果hs
哈希表中包含ht
哈希表中的所有字符,并且对应的个数都不小于ht
哈希表中各个字符的个数,那么说明当前的窗口是可行的,可行中的长度最短的滑动窗口就是答案。
过程如下:
1、遍历t
字符串,用ht
哈希表记录t
字符串各个字符出现的次数。
2、定义两个指针j
和i
,j
指针用于收缩窗口,i
指针用于延伸窗口,则区间[j,i]
表示当前滑动窗口。首先让i
和j
指针都指向字符串s
开头,然后枚举整个字符串s
,枚举过程中,不断增加i
使滑动窗口增大,相当于向右扩展滑动窗口。
3、每次向右扩展滑动窗口一步,将s[i]
加入滑动窗口中,而新加入了s[i]
,相当于滑动窗口维护的字符数加一,即hs[s[i]]++
。
4、对于新加入的字符s[i]
,如果hs[s[i]] <= ht[s[i]]
,说明当前新加入的字符s[i]
是必需的,且还未到达字符串t
所要求的数量。我们还需要事先定义一个cnt
变量, cnt
维护的是s
字符串[j,i]
区间中满足t
字符串的元素的个数,记录相对应字符的总数。新加入的字符s[i]
必需,则cnt++
。
5、我们向右扩展滑动窗口的同时也不能忘记收缩滑动窗口。因此当hs[s[j]] > ht[s[j]
时,说明hs
哈希表中s[j]
的数量多于ht
哈希表中s[j]
的数量,此时我们就需要向右收缩滑动窗口,j++
并使hs[s[j]]--
,即hs[s[j ++ ]] --
。
6、当cnt == t.size
时,说明此时滑动窗口包含符串 t
的全部字符。我们重复上述过程找到最小窗口即为答案。
最后
小编精心为大家准备了一手资料
以上Java高级架构资料、源码、笔记、视频。Dubbo、Redis、设计模式、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术
【附】架构书籍
- BAT面试的20道高频数据库问题解析
- Java面试宝典
- Netty实战
- 算法
BATJ面试要点及Java架构师进阶资料
据库问题解析
2. Java面试宝典
3. Netty实战
4. 算法
[外链图片转存中…(img-qUJiP159-1714413511201)]
BATJ面试要点及Java架构师进阶资料
[外链图片转存中…(img-ZyAnIRsj-1714413511202)]