题目描述
给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。
示例:
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
说明:
如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-window-substring
思路
双指针,动态地维护两个指针。尾指针不断往后面扫,直到包含所有的子串,然后开始收缩头指针,直到不能收缩为止。
c++
class Solution {
public:
string minWindow(string s, string t) {
if(s.empty() || s.size() < t.size()) return "";
const int ASCII_MAX = 256;
int expectCount[ASCII_MAX];
int appearedCount[ASCII_MAX];
fill(expectCount, expectCount + ASCII_MAX, 0);
fill(appearedCount, appearedCount + ASCII_MAX, 0);
for(int i = 0; i < t.size(); i++){
expectCount[t[i]] += 1;
}
int wntStart = 0, wntEnd = 0;
int minLength = INT_MAX, minStart = 0;
int appeared = 0;
for(; wntEnd < s.size(); wntEnd++){
if(expectCount[s[wntEnd]] > 0){
appearedCount[s[wntEnd]] ++;
if(appearedCount[s[wntEnd]] <= expectCount[s[wntEnd]])
appeared ++;
}
if(t.size() == appeared){
while(appearedCount[s[wntStart]] > expectCount[s[wntStart]] || expectCount[s[wntStart]] == 0){
appearedCount[s[wntStart]] --;
wntStart ++;
}
if(minLength > (wntEnd - wntStart + 1)){
minLength = wntEnd - wntStart + 1;
minStart = wntStart;
}
}
}
if(minLength == INT_MAX) return "";
else
return s.substr(minStart, minLength);
}
};