leetcode76 最小覆盖子串(Hard)
题目来源:leetcode76 最小覆盖子串
题目描述:
给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。
示例:
输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"
说明:
如果 S 中不存这样的子串,则返回空字符串 ""。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
解题思路:
滑动窗口的方法。参考labuladong题解思路
1、我们在字符串 s 中使用双指针中的左右指针技巧,初始化 left = right = 0,把索引闭区间 [left, right] 称为一个「窗口」。
2、我们先不断地增加 right 指针扩大窗口 [left, right],直到窗口中的字符串符合要求(包含了 t 中的所有字符)。
3、此时,我们停止增加 right,转而不断增加 left 指针缩小窗口 [left, right],直到窗口中的字符串不再符合要求(不包含t 中的所有字符了)。同时,每次增加 left,我们都要更新一次最小子串长度的结果。
4、重复第 2 和第 3 步,直到 right 到达字符串 s 的尽头。
class Solution {
public:
string minWindow(string s, string t) {
int left=0,right=0,start=0,minLen=INT_MAX;
map<char,int> window;
map<char,int> needs;
int i;
for(i=0;i<t.size();i++)
needs[t[i]]++;
int match=0;
while(right<s.size()){
char c1=s[right];
if(needs.count(c1)){
window[c1]++;
if(window[c1]==needs[c1]) match++;
}
right++;
while(match==needs.size()){
if(right-left<minLen){
start=left;
minLen=right-left;
}
char c2=s[left];
if(needs.count(c2)){
window[c2]--;
if(window[c2]<needs[c2]) match--;
}
left++;
}
}
return minLen==INT_MAX?"":s.substr(start,minLen);
}
};