76.最小覆盖子串
我的解法:
滑动窗口:
- 使用map1记录子串t中各字符的出现频数,map2记录子串s的滑动窗口[left, right]中各字符的出现频数;
- 当s[right]字符是所需字符时,即t中该字符数量大于等于s的滑动窗口中这一字符的数量时,将match加1;
- 当s的滑动窗口左端元素冗余时,直接将窗口向右收缩直至左端元素非冗余,得到的新滑动窗口仍满足包含t中所有字符(因为收缩的元素都是冗余元素);
- 使用res记录s中涵盖t所有字符的最小子串;
- 最后还有一步对match的判断,小于t.size()就代表s不存在涵盖所有t中字符的子串
cpp
class Solution {
public:
string minWindow(string s, string t) {
if(s.size() < t.size()){
return "";
}
string res = s;
int left = 0, right = 0;
int match = 0;
unordered_map<char, int> map1, map2;
for(auto ch : t){
map1[ch]++;
}
while(right < s.size()){
map2[s[right]]++;
if(map1[s[right]] >= map2[s[right]]){
match++;
}
while((left < right) && (map1[s[left]] < map2[s[left]])){
map2[s[left++]]--;
}
if(match == t.size()){
if(right - left + 1 < res.size()){
res = s.substr(left, right - left + 1);
}
}
right++;
}
return match == t.size() ? res : "";
}
};