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

9.《滑动窗口篇》---①长度最小的子数组(中等)

滑动窗口推导过程

我们不能说一上来就知道这个题目用滑动窗口,然后就使用滑动窗口的方法来做这个题目。

首先我们想到的应该是暴力解法。

接着再优化为滑动窗口

由于数字都是 ≥ 0 的数。因此累加的数越多。和越大。

因此right往后遍历的时候。当发现sum > target 就可以不用再往右移动了。

此时left往右移动一位。

按照暴力枚举。right 还需要从新回到left的位置。再次计算累加和是否≥target。

而我们发现 (使用暴力解法的时候两个指针可以不会退。就可以用滑动窗口了)

此时只需要让sum-2 然后再次判断。就可以了。而right不用移动。

这就引入了滑动窗口。

利用单调性,+同向双指针。

滑动窗口的使用:

1. left = 0,right =0;

2.进窗口

3.判断

4.出窗口

方法一:暴力解法

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int n = nums.length;
        int minLen = Integer.MAX_VALUE;// 用于存储最短子数组的长度

        for(int i = 0; i < n; i++){
            int sum = 0;// 每次外层循环重新初始化sum
            for(int j =i; j<n; j++){
                sum += nums[j];// 计算子数组的和
                if(sum >= target){// 如果子数组的和大于或等于目标值
                    minLen = Math.min(j-i+1,minLen);// 更新最短长度
                    break;// 提前结束当前内层循环,因为长度已经达到条件
                }
            }
        }
        return minLen == Integer.MAX_VALUE ? 0 : minLen;
        // 如果没有符合条件的子数组,返回0
    }
}   

复杂度分析 

  • 时间复杂度: O(n2)O(n^2)O(n2)(嵌套双重循环导致的平方复杂度)
  • 空间复杂度: O(1)O(1)O(1)(只使用了常量级别的额外空间)

 解法二:滑动窗口(利用单调性+ “同向双指针”)

1.left = 0,right = 0

2.进窗口。我们让right++,并且 sum += nums[right];

3.判断条件。使用while循环判断

4.出窗口:sum -= nums[left++];

注意:

判断条件的时候一定要使用while循环。而不是if。

因为left++一次之后。也可能继续满足条件。

如果使用 if 很可能会漏掉正确答案。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int n = nums.length;
        int minLen = Integer.MAX_VALUE;// 用于存储最短子数组的长度
        int sum = 0;

        for(int left = 0,right =0; right < n; right++){
            sum += nums[right];
            while(sum >= target){
                minLen = Math.min(right-left+1,minLen);
                sum -= nums[left++];
            }
        }
        return minLen == Integer.MAX_VALUE ? 0 : minLen;
    }
}  

复杂度分析

时间复杂度:O(n)。n是数组的长度。指针 left 和 right 最多各移动一次。

空间复杂度:O(1)。


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

相关文章:

  • 解决 Cannot read properties of undefined报错
  • 【Redis】实现异步秒杀功能
  • 儿童玩具安全检测GB6675标准详细介绍
  • 深入理解分页及 PageHelper 使用细节与注意事项
  • Python设计模式详解之5 —— 原型模式
  • 【Docker】在 Ubuntu 上安装 Docker 的详细指南
  • Elasticsearch 查看磁盘占用 查看指定索引磁盘占用
  • SpringBoot 2.2.10 无法执行Test单元测试
  • Excel数据动态获取与映射
  • MySQL SELECT 语句执行链路解析
  • C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
  • 24.UE5枚举,怪物分类,龙卷风技能
  • LLaMA与ChatGLM选用比较
  • 无插件H5播放器EasyPlayer.js RTSP播放器chrome/edge等浏览器如何使用独立显卡
  • 构建安全护盾:HarmonyOS 应用的数据安全审计与日志管理实战
  • 自动驾驶系列—告别眩光烦恼:智能大灯如何守护夜间行车安全
  • Linux(命令行扩展+命令行历史 大白话+图片)
  • 查询我正在学习的课程
  • C++:指针和引用
  • 速盾:cdn影响获取ip吗?
  • 21-JavaScript 解构赋值简介
  • Android:任意层级树形控件(有效果图和Demo示例)
  • 项目-摄像
  • python学习笔记1
  • 基于深度学习的文本信息提取方法研究(pytorch python textcnn框架)
  • 机器学习笔记 // 度量ML预测的准确率