76. Minimum Window Substring
Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
Example:
Input: S = "ADOBECODEBANC", T = "ABC"
Output: "BANC"
Note:
If there is no such window in S that covers all characters in T, return the empty string “”.
If there is such window, you are guaranteed that there will always be only one unique minimum window in S.
方法1:
思路:
先遍历一遍T来统计所有字符出现的次数。
左指针指向第一次出现的字母之一,操作hashmap记录右指针指向的位置出现的次数变化,同时累计count,也就是满足了多少个T的字母。注意这里如果出现了S[char]<0,那么不应该count++,因为并不奏效。按这个规则遍历,如果所有要求的字符都已经出现过了,也就是count == t.size(),可以记录一下result,并且尝试抛弃左指针的字母。这时应该移动到下一个有意义的字符位置,每次抛弃一个,就在相应的S[char]–,并且count减少。再次注意,如果S[char] <= 0(和上面的条件不一样),不应该count–,因为抛弃的不是需要的字母。那么只要查询S[char] 是否> 0,就知道有意义与否(无意义的永远是负数)。
需要的数据结构:
- unordered_map<char, int> S: 记录sliding window中每个字符出现的次数
- int count : 记录当前sliding window中一共有多少个match
- string result
易错点
- count的增减:count在减少的时候,如果S[s[right]]>= 0 就可以–;而减少时,只要S[s[right]]> 0 就可以++。想清楚为什么。
Complexity
Time complexity: O(n)
Space complexity: O(n)
class Solution {
public:
string minWindow(string s, string t) {
string result ="";
unordered_map<char, int> S;
for (char c: t) S[c] ++;
int left = 0, count = 0, minlen = INT_MAX;
for (int right = 0; right < s.size(); right++){
if (--S[s[right]] >= 0) count ++;
while (count == t.size()){
if (right - left + 1 < minlen){
minlen = right - left + 1;
result = s.substr(left, minlen);
}
if (++S[s[left]] > 0) count--;
left ++;
}
}
return result;
}
};