算法--滑动窗口(一)

算法原理

滑动窗口

算法思路:

问题分析的对象一般是一段连续的区间

这个窗口寻找的是:以当前窗口最左侧元素(left1)为基准,符合条件的情况找到right,此时是left1的最优解

那么我们就可以大胆的把left1舍去,那么我们left右移,如果让right从头开始必然会有很多重复的计算,我们就可以让right先不动,如果不满足要求,那么right++,则可知left和right是同向移动的,不回退的,所以时间复杂度是O(N)

题目解析

1.长度最小的子数组

https://leetcode.cn/problems/minimum-size-subarray-sum/

题目解析

给定一个含有n个正整数的数组和一个目标t,找出数组中满足和>t的长度最小的连续子数组,返回其长度不存在,返回0

算法原理

解法一:暴力解法 暴力枚举出所有子数组的和

解法二:利用单调性,使用滑动窗口进行优化

代码实现

复制代码
    public int minSubArrayLen(int target, int[] nums) {
        int n=nums.length,sum=0;
        int len=Integer.MAX_VALUE;
        for(int left=0,right=0;right<n;right++){
            sum+=nums[right];
            while(sum>=target){
                len=Math.min(len,right-left+1);
                left++;
                sum-=nums[left-1];
            }
        }
        return len==Integer.MAX_VALUE?0:len;
    }

2.无重复字符的最长子串

https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/

题目解析

给定一个字符串s,请你找出不含重复字符的最长子串的长度

算法原理

解法一:暴力枚举+哈希表(哈希表可以发现重复字符)

解法二:滑动窗口

代码实现

复制代码
class Solution {
    public int lengthOfLongestSubstring(String ss) {
       char[] s=ss.toCharArray();
       int[] hash=new int[128];
       int left=0,right=0,n=ss.length(),ret=0;
       while(right<n){
        hash[s[right]]++;
        while(hash[s[right]]>1){
            hash[s[left++]]--;
        }
        ret=Math.max(ret,right-left+1);
        right++;
       }
       return ret;
    }
}

3.最大连续一的个数

https://leetcode.cn/problems/max-consecutive-ones-iii/description/

题目解析

给定一个二进制数组nums和一个整数k,如果最多可以翻转k个0,则返回数组中连续1的最大个数

(最多可以不一定刚好1个)

算法原理

翻转<->找到连续区域的0不超过k个

解法一:暴力解法 固定起点,进行枚举+zero计数器

解法二:滑动窗口

代码实现

复制代码
class Solution {
    public int longestOnes(int[] nums, int k) {
      int n=nums.length,ret=0;
      for(int left=0,right=0,zero=0;right<n;right++){
        if(nums[right]==0){
            zero++;
        }
        while(zero>k){
            if(nums[left]==0){
                zero--;
            }
            left++;
        }
        ret=Math.max(ret,right-left+1);
      }
      return ret;
    }
}

4.将x减到0的最小操作数

题目解析

给定一个nums数组和x,每次应移除nums最左或最右的值,然后从x中减去该元素的值,需要修改数组以供接下来使用,如果可以恰好减到0,返回最小操作数,否则返回-1;

算法原理

如果直接按照题目要求操作会有点难,所以我们将换一种思路

解法一:暴力解法

解法二:滑动窗口

1.left=0,right=0

2.进窗口 tmp+=nums【right】

3.判断 tmp>sum-x;

出窗口 tmp-=nums[left]

更新结果 tmp==sum-t

代码实现

复制代码
class Solution {
    public int minOperations(int[] nums, int x) {
        int sum=0;
        for(int a:nums){
            sum+=a;
        }
        int t=sum-x;
        if(t<0){
            return -1;
        }
        int ret=-1;
        for(int left=0,right=0,tmp=0;right<nums.length;right++){
            tmp+=nums[right];
            while(tmp>t){
                tmp-=nums[left++];
            }
            if(tmp==t){
                ret=Math.max(ret,right-left+1);
            }
        }
        if(ret==-1){
            return -1;
        }else{
              return nums.length-ret;
        }
      
    }
}
相关推荐
王哈哈^_^4 小时前
【数据集】【YOLO】【目标检测】农作物病害数据集 11498 张,病害检测,YOLOv8农作物病虫害识别系统实战训推教程。
人工智能·深度学习·算法·yolo·目标检测·计算机视觉·1024程序员节
xier_ran4 小时前
邻接矩阵的 k 次幂意味着什么?从图论到路径计数的直观解释
算法·图论
B站_计算机毕业设计之家5 小时前
预测算法:股票数据分析预测系统 股票预测 股价预测 Arima预测算法(时间序列预测算法) Flask 框架 大数据(源码)✅
python·算法·机器学习·数据分析·flask·股票·预测
想唱rap6 小时前
C++ list 类的使用
c语言·开发语言·数据结构·c++·笔记·算法·list
l1t6 小时前
利用DuckDB SQL求解集合数学题
数据库·sql·算法·集合·duckdb
yuyanjingtao6 小时前
CCF-GESP 等级考试 2024年9月认证C++四级真题解析
c++·算法·青少年编程·gesp·csp-j/s
微笑尅乐6 小时前
洗牌算法讲解——力扣384.打乱数组
算法·leetcode·职场和发展
Lei_3359676 小时前
[算法]背包DP(01背包、完全背包问题、多重背包、分组背包、混合背包问题、有依赖的背包问题等)
c++·算法
uesowys6 小时前
华为OD算法开发指导-比赛的冠亚季军
算法·华为od