当前位置: 首页 > article >正文

优选算法精品课--滑动窗口算法(一)

滑动窗口算法(一)

  • (一) 长度最小的子数组
    • 1.1 题目分析
    • 1.2 算法原理
    • 1.3 代码实现
  • (二)无重复字符的最长子串
    • 2.1 题目分析
    • 2.2 算法原理
    • 2.3 代码实现
  • (三)最大连续1的个数 III
    • 3.1 题目分析
    • 3.2 算法原理
    • 3.3 代码实现
  • (四)将 x 减到 0 的最小操作数
    • 4.1 题目分析
    • 4.2 算法原理
    • 4.3 代码实现

(一) 长度最小的子数组

题目链接:
https://leetcode.cn/problems/minimum-size-subarray-sum/

1.1 题目分析

在这里插入图片描述
这道题要求我们在数组中找一个区间,这个区间的元素的和等于题目给出的target,如果找不到则返回-1.

1.2 算法原理

解法一:暴力遍历出所有的区间,然后找到最小区间
如果我们按照这种方法就需要两个循环才能解决问题,时间复杂度为O(n^2).效率非常的低

解法二:利用单调性,使用同向双指针(同向双指针就是我们的滑动窗口)

在这里插入图片描述

在这里插入图片描述

1.3 代码实现

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int left=0,right=0,sum=0,len=INT_MAX;

        int n=nums.size();
        while(right<n)
        {
            sum+=nums[right];//入窗口
            while(sum>=target)//判断
            {
                len=min(len,right-left+1);//更新len
                sum-=nums[left++];//划出窗口
            }
            right++;//再入窗口
        }

        return len==INT_MAX?0:len;
    }
};

(二)无重复字符的最长子串

题目链接:
https://leetcode.cn/problems/longest-substring-without-repeating-characters/

2.1 题目分析

在这里插入图片描述
题目的意思就是让我们取找一个区间,在这个区间里的元素没有重复,返回区间的大小。

2.2 算法原理

解法一:暴力枚举+哈希表(去重)

解法二:根据规律,使用滑动窗口来解决问题

在这里插入图片描述
像上面两个常见的例子,我们的算法逻辑是将right所在的元素入哈希表,如果出现重复,我们就让left++,当重复消失,这时更新一下len即可。

在这里插入图片描述

2.3 代码实现

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int left=0,right=0,len=0;
        int a[128]={0};//用来观察是否有重复

        while(right<s.size())
        {
            a[s[right]]++;//入窗口
            while(a[s[right]]>1)
            {
                a[s[left++]]--;
            }
            len=max(len,right-left+1);
            right++;
        }

        return len;
    }
};

(三)最大连续1的个数 III

题目链接:
https://leetcode.cn/problems/max-consecutive-ones-iii/

3.1 题目分析

在这里插入图片描述
这个题的意思就是让我们找两个0的位置去翻转为1,使全部为1的区间长度最长。

3.2 算法原理

在这里插入图片描述
这道题需要我们转换一下思路,如果我们老老实实的按照题目中的那样先将一个0翻转为1,再找一个0翻转为1,那就太复杂了,那我们转换一下思路,我们是不是可以找一个区间,这个区间里0的个数为题目中的k,然后求这个区间最大的长度即可。

在这里插入图片描述
需要注意的是我们再入右区间的时候,如上图所示,这种情况下,left需要++,只要left位置还等于1,那区间一定在缩小,所以要是left当前的值不为0就直接跳过即可。

在这里插入图片描述

3.3 代码实现

class Solution {
public:
    int longestOnes(vector<int>& nums, int k) {
        int left=0,right=0,count0=0,len=0;

        int n=nums.size();
        while(right<n)
        {
            if(nums[right]==0)  count0++;//入窗口
            while(count0>k)//判断
            {
                if(nums[left]==1) left++;//跳过
                else
                {
                    left++;
                    count0--;//结束
                }
            }
            len=max(len,right-left+1);//更新len
            right++;
        }

        return len;
    }
};

(四)将 x 减到 0 的最小操作数

题目链接:
https://leetcode.cn/problems/minimum-operations-to-reduce-x-to-zero/

4.1 题目分析

在这里插入图片描述
这道题就是让我们在左右区间来删除元素,使题目中的x最后为0。

4.2 算法原理

这道题也需要我们转换一下思路,如果我们来按照题目中的方法来左右一个一个删除的话,情况太多了,所以我们可以来找反面,正所谓“正难则反”嘛,所以我们就去找中间的区间,让中间的区间元素和为数组总元素和与x之差相等,再用一次滑动窗口求解出这个区间即可。
在这里插入图片描述

4.3 代码实现

class Solution {
public:
    int minOperations(vector<int>& nums, int x) {
        int sum=0;
        for(int i=0;i<nums.size();i++)
        {
            sum+=nums[i];
        }
        int target=sum-x;

        if(target<0)
            return -1;
            
        int left=0,right=0,len=-1,count=0;
        while(right<nums.size())
        {
            count+=nums[right];
            while(count>target)
            {
                count-=nums[left++];
            }
            if(count==target)
                len=max(len,right-left+1);
            right++;
        }

        if(len==-1)
            return len;
        else
            return nums.size()-len;
    }
};

http://www.kler.cn/a/384504.html

相关文章:

  • 验证二叉搜索树
  • Tomcat(4) Tomcat支持哪些版本的Java?
  • 【harbor】离线安装2.9.0-arm64架构服务制作和升级部署
  • Aop+自定义注解实现数据字典映射
  • 推荐一款基于Flash的交互式园林设计工具:Garden Planner
  • GooglePlay: 应用和游戏的内容分级
  • 笔记--(网络3)、交换机、VLAN
  • 大数据治理:构建数据驱动的智能未来
  • Springboot集成syslog+logstash收集日志到ES
  • Linux -- 操作系统(软件)
  • 软件测试—功能测试详解
  • 智能家居的未来:AI让生活更智能还是更复杂?
  • 【Linux】- 权限(2)
  • RK3568笔记六十八:Yolov11目标检测部署测试
  • 【redis】redis缓存和数据库保证一致性的方案
  • 香港航空 阿里滑块 acw_sc__v3 分析
  • 10DSP学习-利用syscfg配置ADC,并使用EPWM触发转换
  • Excel打开Python创建的csv文件乱码
  • 《Kotlin实战》-第09章:泛型
  • 【人工智能】ChatGPT多模型感知态识别
  • oneplus6-build.md
  • 浏览器中的事件循环
  • KTHREAD结构-->ApcState
  • HbuildderX运行到手机或模拟器的Android App基座识别不到设备 mac
  • Shiro安全认证技术实践
  • 神经网络基础--什么是正向传播??什么是方向传播??