给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。
注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。
示例 1:
输入:s = “ADOBECODEBANC”, t = “ABC”
输出:“BANC”
示例 2:
输入:s = “a”, t = “a”
输出:“a”
提示:
1 <= s.length, t.length <= 105
s 和 t 由英文字母组成
进阶:你能设计一个在 o(n) 时间内解决此问题的算法吗?
定义边界l,r。判断边界里的字符串是否满足条件。若满足,l右移,否则r右移。
class Solution {
public:
static const int maxn = 256;
int a[maxn];
int b[maxn];
string minWindow(string s, string t) {
for(int i = 0; i < t.size(); i++)
a[t[i]]++;//目标串里每个字符各有多少个
string ans = "";
int l = 0, r = -1, sum = 0, tar = 0, mx= 1e9;
for(int i = 0; i < maxn; i++)
if(a[i]) tar++;//目标串里有多少个不同的字符
int al = 0, ar = 0, asum = 0;
while(r < (int)s.size()) {
if(sum == tar) {//若满足条件
if(r - l < mx) {
ar = r, al = l;
mx = r - l;
}
b[s[l]]--;
if(b[s[l]] < a[s[l]]) sum--;
l++;
}
else {//若不满足
r++;
if(r == s.size()) break;
if(++b[s[r]] == a[s[r]]) sum++;
}
}
if(mx != 1e9)
for(int i = al; i <= ar; i++) ans += s[i];
return ans;
}
};