总体的思路是用两个哈希表,一个保存的是所需要的,一个保存的是现在现有的,通过不断对比,决定是否添加或者删除
滑动窗口的总是思想就是,先加入元素,等到元素满足以后,在移动左边的指针,不断查看是否满足条件,如果不满足,就就继续向右边移动。在不断两个指针不断移动的过程中,保存好找到的最优解。
class Solution {
public:
string minWindow(string s, string t) {
unordered_map<char, int> need,have;
int left = 0;
int count = 0;
int len = INT_MAX;
int start = 0;
// 表示对应字母所需要的个数
for(char c : t)
need[c]++;
for(int right = 0; right < s.size();right++)
{
// 如果当前遍历的元素是所需要的
if(need.find(s[right]) != need.end())
{
have[s[right]]++;
if(have[s[right]] == need[s[right]]) // 满足条件以后,count只加一次,所以是 ==
count++;
}
// 已经满足条件了
while(count == need.size())
{
// 更新len,记录下起始位置
if(len > right - left + 1)
{
start = left;
len = right - left + 1;
}
// 如果当前移除的元素刚好是所需要的
if(need.find(s[left]) != need.end())
{
if(need[s[left]] == have[s[left]])
count--; // 因为移除之后就不满足条件了,所以count--
have[s[left]]--;
}
// 移动
left++;
}
}
return len == INT_MAX ? "" : s.substr(start, len);
}
};