数据结构与算法:滑动窗口

前言

滑动窗口一般主要用于解决子数组或子串问题,这类的题目更看重对题目的分析和转化。

一、原理

在整个数组上,用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);
            }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值