题目: 给定两个字符串 S 和 T,求 S 中包含 T 所有字符的最短连续子字符串的长度,同时要求时间
复杂度不得超过 O(n)。
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
方法一: 滑动窗口
class Solution {
public:
string minWindow(string s, string t) {
vector<int> chars(128, 0);
vector<bool> flag(128, false);
// 先统计 t 中的字符情况
for (int i=0; i<t.size(); ++i){
flag[t[i]] = true;
++chars[t[i]];
}
// 移动滑动窗口,不断更改统计数据
int cnt = 0, l = 0, min_l = 0, min_size = s.size() + 1;
for (int r=0; r<s.size(); ++r){
if (flag[s[r]]){
if (--chars[s[r]] >= 0){
++cnt;
}
// 若目前滑动窗口已包含 t 中全部字符
// 则尝试将 l 右移,在不影响结果的情况下获得最短子字符串
while (cnt == t.size()){
if (r - l + 1 < min_size){
min_l = l;
min_size = r - l + 1;
}
if (flag[s[l]] && ++chars[s[l]] > 0){
--cnt;
}
++l;
}
}
}
return min_size > s.size() ? "" : s.substr(min_l, min_size);
}
};
复杂度分析
时间复杂度: 最坏情况下左右指针对 s 的每个元素各遍历一遍,哈希表中对 s 中的每个元素各插入、删除一次,对 t 中的元素各插入一次。O(C.|s| + |t|)
空间复杂度: 每张哈希表最多不会存放超过字符集大小的键值对, O©