关于滑动窗口的理解
滑动窗口有以下几个优点
- 线性时间复杂度:滑动窗口的方法通常可以在线性时间复杂度内解决问题,因为每个元素只会被访问一次。
- 空间复杂度较低:滑动窗口的方法通常只需要维护一个固定大小的窗口,因此空间复杂度相对较低。
- 可扩展性强:滑动窗口的方法通常可以很容易地扩展到多维情况,例如二维数组或字符串
- 解决区间问题的高效方法:滑动窗口通常用于解决区间问题,例如字符串中的最长子串、最小覆盖子串等问题,能够高效地解决这些问题。
- 可以通过双指针优化:滑动窗口通常可以通过双指针优化,即使用左右指针维护窗口的位置,来进一步提高效率。
滑动窗口的举例理解
假设我们要在一个数组中找到和为 k 的连续子数组,我们可以使用滑动窗口的方法来解决这个问题。首先,我们设置左右两个指针,分别指向数组的起始位置。然后,我们不断向右移动右指针,同时维护窗口内的元素之和。如果窗口内的元素之和等于 k,那么我们就找到了一个解。否则,如果窗口内的元素之和大于 k,那么我们就向右移动左指针,缩小窗口大小,直到窗口内的元素之和等于 k 或者小于 k。
题目描述
题目分析
这个实际上就是要设置一个滑动窗口 ,窗口里保持t是子串 不断的进行窗口边界的更新以及窗口内值的更新
代码示例
class Solution {
public:
string minWindow(string s, string t) {
unordered_map<char, int> tmap; // t的哈希表
unordered_map<char, int> smap; // 记录窗口的哈希表
int left = 0;
int nums = 0; // 记录当前窗口中符合条件的有几个字符
string res = s + "initialize a max string";
for(auto item : t)
// 将t中的字符记录在哈希中
++tmap[item];
// for右边界
for(int right=0; right<s.size(); ++right)
{
// 将当前的值记录进窗口的哈希表中
++smap[s[right]];
// 窗口中的字符不够
if(tmap[s[right]] >= smap[s[right]])
{
++nums;
}
// 窗口中的元素满了 不断进行++找到下一个元素
while(left<right && smap[s[left]]>tmap[s[left]])
{
--smap[s[left++]];
}
if(nums == t.size())
{ // 这里维持一个最小值
if (right - left + 1 < res.size())
res = s.substr(left, right - left + 1);
}
}
return res == s + "initialize a max string" ? "" : res;
}
};