前言
滑动窗口一般主要用于解决子数组或子串问题,这类的题目更看重对题目的分析和转化。
一、原理
在整个数组上,用l和r分别控制窗口的左右边界,r++就扩大,l++就减小。
当窗口的范围和题目中某个指标间存在单调关系时,就可以考虑使用滑动窗口解决,整个过程一般会需要用某种数据结构或算法来维护信息,每次统计的就是子数组以每个位置开头或结尾的答案。
二、题目
1.无重复字符的最长子串
class Solution {
public:
int lengthOfLongestSubstring(string s) {
map<int,int>mp;
map<int,int>::iterator iter;
int ans=0;
for(int l=0,r=0;r<s.length();r++)
{
iter=mp.find(s[r]);
if(iter!=mp.end())
{
l=max(l,mp[s[r]]+1);
}
ans=max(ans,r-l+1);
mp[s[r]]=r;
}
return ans;
}
};
首先分析题目可以发现存在单调性:窗口越大,越可能出现重复字符。
之后,考虑重复这一性质,可以用一个哈希map来维护每个字符最晚出现的位置,这样当遇到重复的字符,直接让l跳到该字符上次出现位置的下一个位置即可。这里注意l只能往前跳!
2.长度最小的子数组
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int ans=INT_MAX;
for(int l=0,r=0,sum=0;r<nums.size();r++)
{
sum+=nums[r];
while(sum-nums[l]>=target)
{
sum-=nums[l];
l++;
}
if(sum>=target)
{
ans=min(ans,r-l+1);
}