最小覆盖子串
给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。
示例:
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
说明:
如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
思路和代码
滑动窗口+哈希
首先用一个哈希表示 t 中每一个字符出现的次数,用一个cnt表示包含 t 中所有元素。遍历S。
i 就是窗口的右边界,若当前元素–letterCnt[s[i]] >= 0说明是 t 中所需要的元素,对于那些不是 t 中的元素或多余的元素,会变成负值。
若cnt == t.size()表示当前的滑动窗口包含所有 t 所需要的字符,这时候应该更新最小长度,同时移动左边界。
class Solution {
public:
string minWindow(string s, string t) {
vector<int> letterCnt(128, 0);
int left = 0, cnt = 0, minLeft = -1, minLen = INT_MAX;
for (char c : t) ++letterCnt[c];
for (int i = 0; i < s.size(); ++i) {
if (--letterCnt[s[i]] >= 0) ++cnt;
while (cnt == t.size()) {
if (minLen > i - left + 1) {
minLen = i - left + 1;
minLeft = left;
}
if (++letterCnt[s[left]] > 0) --cnt;
++left;
}
}
return minLeft == -1 ? "" : s.substr(minLeft, minLen);
}
};