题目:
Given two strings s
and t
of lengths m
and n
respectively, return the minimum window in s
which will contain all the characters in t
. If there is no such window in s
that covers all characters in t
, return the empty string ""
.
Note that If there is such a window, it is guaranteed that there will always be only one unique minimum window in s
.
Example 1:
Input: s = "ADOBECODEBANC", t = "ABC" Output: "BANC"
Example 2:
Input: s = "a", t = "a" Output: "a"
Constraints:
m == s.length
n == t.length
1 <= m, n <= 105
s
andt
consist of English letters.
Follow up: Could you find an algorithm that runs in O(m + n)
time?
思路:
follow up中要求时间复杂度在,这里用滑动窗口法。两个字符串,我们要在S中找出最短的含有T的所有字母的子串。需要两个哈希map来记录:一个cur是需要记录当前窗口中字母以及出现的个数,另一个need很明显记录T字符串中的字母以及个数,作为对照。接着就是在while循环中不断将窗口右端先向右移动(最开始的时候窗口为空),这时加入新的字符,同时更新两个哈希map中的数值,以及检查是否当前字母已经符合T中当前字母的数量,如果符合,valid增加一。这个valid即用来表示窗口中满足need的条件个数,因此只要valid和need的size是相同的,当前窗口的子串就符合我们的要求。然后在同一个while中检查窗口左端是否要右移,当然这要基于valid是否满足的情况下。如果要右移,首先记录当前窗口的长度,是否需要更新,因为我们要找最短的子串。其次就是左端右移并且更新两个哈希map中的信息,这里和右端右移是对称的。最终返回我们记录的最短子串即可。
代码:
class Solution {
public:
string minWindow(string s, string t) {
unordered_map<char,int> need, cur;
for(auto c:t)
need[c]++;
int left=0, right=0, valid=0;
int start=0, len=INT_MAX;
while(right<s.size())
{
char c=s[right];
// move right
right++;
// check the need string, if the specific char is same with the need one, we can make valid plus one
if(need.count(c)){
cur[c]++;
if(cur[c]==need[c]){
valid++;
}
}
//check if need move left
while(valid==need.size())
{
if(right-left<len){
start=left;
len=right-left;
}
char d=s[left];
left++;
if(need.count(d)){
if(cur[d]==need[d]){
valid--;
}
cur[d]--;
}
}
}
return len==INT_MAX?"":s.substr(start,len);
}
};