【算法】滑动窗口——长度最小的子数组

news2024/11/25 14:40:59

本篇文章是用一个实例来介绍常用算法之一“滑动窗口”的相关概念,有需要借鉴即可。

目录

  • 1.题目
  • 2.暴力求解
    • 2.1暴力求解思路:
    • 2.2时间复杂度是多少?
  • 3.暴力求解的优化
    • 3.1固定left的情况下,优化right的次数。
    • 3.2sum求值优化
    • 3.3不同组之间left与right包含关系的优化
  • 4.滑动窗口算法
    • 4.1概念
    • 4.2应用场景
    • 4.3使用
    • 4.4正确性
    • 4.5时间复杂度
  • 5.题解代码示例

1.题目

想要介绍一个算法,没有具体的例子来说算法是非常抽象的,算法是一种思想,因而为了介绍有关滑动窗口的概念,用下面例子来做相关介绍。

题目链接:LINK
在这里插入图片描述
看到这个题目我们先不论什么是“滑动窗口”这种算法,我们先从最简单的暴力求解来思考,顺着暴力求解的思路一步一步优化,最终达到“滑动窗口”的算法效果。

2.暴力求解

2.1暴力求解思路:

两个指针,一个left,一个right,加上left和right之间的所有数跟target进行比较,找到最小的len即可。

我们以上面的题目为例子,以题目中示例1为具体的操作对象:

left和right的组合共有36种情况,如下图所示:
在这里插入图片描述

2.2时间复杂度是多少?

答:left和right两层循环并且求sum时候需要再遍历一次,所以是N^3

当然这种代码很挫哈,为了提高效率,我们引出“滑动窗口”这一算法思想。

3.暴力求解的优化

滑动窗口是一种高效的算法,说白了也是从暴力求解的思路中优化过来的,所以我们一步一步来优化该暴力求解思路,来更加高效。

3.1固定left的情况下,优化right的次数。

在同一个left的情况下,很多时候right是多余的。比如说2 + 3 + 1 + 2 = 8早就超过target = 7了,暴力求解还在继续向后加…这很多余。
在这里插入图片描述

3.2sum求值优化

求和的时候,每次left和right变的情况下都要重新计算,十分耗费性能。我们想是不是可以利用一下上一次的sum值来求这次的sum值?
在这里插入图片描述
经过优化,这样就基本接近滑动窗口算法了。但还不是。这时的时间复杂度是O(N^2)
在本题中大概优化到下面效果:
在这里插入图片描述

大概就是下面的代码:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) 
    {
        int ret = INT_MAX;
        int n = nums.size();
        // 枚举出所有满⾜和⼤于等于 target 的⼦数组[start, end]
        // 由于是取到最⼩,因此枚举的过程中要尽量让数组的⻓度最⼩
        // 枚举开始位置
        for (int start = 0; start < n; start++)
        {
        int sum = 0; // 记录从这个位置开始的连续数组的和
        // 寻找结束位置
        for (int end = start; end < n; end++)
        {
         sum += nums[end]; // 将当前位置加上
 
        if (sum >= target) // 当这段区间内的和满⾜条件时
           {
           // 更新结果,start 开头的最短区间已经找到
           ret = min(ret, end - start + 1);
           break;
           }
        }
        }
        // 返回最后结果
        return ret == INT_MAX ? 0 : ret;
    }
};

不用怀疑,力扣过不了哈。
在这里插入图片描述

3.3不同组之间left与right包含关系的优化

这个是什么意思呢?
嗯…经过上面所说的两步之后,我们就发现以上面的题目来举例,暴力求解就可以达到下面这种优化效果:
在这里插入图片描述
当然,上面超出时间限制截图告诉我们,继续优化…
但是我们发现一个问题,比如拿下面的例子来说(看蓝色框)
在这里插入图片描述
放大一点:
在这里插入图片描述
就是这种不满足的包含情况下也可以优化掉。
下面是真正的滑动窗口优化图:
在这里插入图片描述

4.滑动窗口算法

4.1概念

基于双指针算法,两指针同向向前且不回退的算法思想。

4.2应用场景

具有一定单调性题目,比如在本节博客的举的这道题种,从left到right不断加就是一种单增关系。

4.3使用

滑动窗口的大体使用步骤是什么呢?

  • 1.left,right
  • 2.进窗口
  • 3.判断
    • 出窗口
    • 更新结果

注:①2、3两步是循环;②本步骤只是大体步骤;

比如说,在本例子中,这个步骤就可以具体为:
在这里插入图片描述

  • 1.先让left = 0,right = 0;
  • 2.进窗口,sum +=2;
  • 3.判断sum < target;
  • 4.所以继续进窗口,让right = 1,sum+=3;
  • 5.继续判断,sum = 5 < target
  • 6.继续进窗口,right = 2,sum+=1
  • 7.继续判断,sum = 6 < target
  • 8.继续进窗口,right = 3,sum+=2
  • 9.继续判断,sum = 8 > target
  • 10.满足条件,出窗口
  • 11.left++,left = 1,sum-=2
  • 12.判断sum = 6 < target
  • 13.right++,right = 4,sum+=4
  • 14.判断sum = 10 > target
  • 。。。

4.4正确性

滑动窗口算法对吗?是正确的。
因为只是在暴力求解的基础上去掉了一些不必要的计算过程。

4.5时间复杂度

对于上面那道题来说,暴力求解是O(N^3),但是滑动窗口是O(N)

5.题解代码示例

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) 
    {
        int ret = INT_MAX;
        int n = nums.size();
        int sum = 0;
       for(int left = 0,right = 0;right < n;right++)
        {
            sum+=nums[right];//进窗口
            while(sum>=target)//判断
            {
                ret = min(ret,right - left + 1);
                sum-=nums[left];//出窗口
                left++;//持续判断
            }
        }
        // 返回最后结果
        return ret == INT_MAX ? 0 : ret;
    }
};

EOF

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1648945.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux高级学习(前置 在vmware安装centos7.4)

【小白入门 通俗易懂】2021韩顺平 一周学会Linux 此文章包含第006p-第p007的内容 操作 在安装好的vmware下进行安装 这里使用的是vmware15&#xff08;win10下&#xff09;&#xff0c;win11可能无法使用15&#xff08;有几率蓝屏&#xff09;&#xff0c;换成16就行了 用迅雷…

OpenAI API搭建的智能家居助手;私密大型语言模型(LLM)聊天机器人;视频和音频文件的自动化识别和翻译工具

✨ 1: GPT Home 基于Raspberry Pi和OpenAI API搭建的智能家居助手 GPT Home是一个基于Raspberry Pi和OpenAI API搭建的智能家居助手&#xff0c;功能上类似于Google Nest Hub或Amazon Alexa。通过详细的设置指南和配件列表&#xff0c;用户可以自行组装和配置这个设备&#x…

GEE数据集——DeltaDTM 全球沿海数字地形模型数据集

DeltaDTM 全球沿海数字地形模型产品 简介 DeltaDTM 是全球沿岸数字地形模型&#xff08;DTM&#xff09;&#xff0c;水平空间分辨率为 1 弧秒&#xff08;∼30 米&#xff09;&#xff0c;垂直平均绝对误差&#xff08;MAE&#xff09;为 0.45 米。它利用 ICESat-2 和 GEDI …

电子合同:纸质合同的未来替代者?

随着科技的迅猛发展&#xff0c;电子合同作为一种新兴的合同形式&#xff0c;逐渐在各行各业中崭露头角。那么&#xff0c;电子合同是否会替代纸质合同&#xff0c;成为未来合同形式的主流呢&#xff1f;本文将就此话题展开探讨。 首先&#xff0c;我们来看电子合同的优势。电…

进制乘法表(任意进制均可以)

#include <iostream> // 包含输入输出流库 #include <vector> // 包含向量库&#xff0c;未使用&#xff0c;可以删除 #include <string> // 包含字符串库using namespace std; // 使用标准命名空间// 将十进制数转换为P进制形式的字符串 string toBase(…

【数据结构与算法】力扣 102. 二叉树的层序遍历

题目描述 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a; root [3,9,20,null,null,15,7] 输出&#xff1a; [[3],[9,20],[15,7]]示例 2&#x…

第8篇:创建Nios II工程之读取Switch的值<一>

Q&#xff1a;本期我们再添加一个PIO组件设为输入&#xff0c;创建Nios II工程读取输入值显示在LED上。 A&#xff1a;在前2期创建的控制LED工程的Platform Designer系统基础上再添加一个PIO核&#xff0c;参数设置为18位和单向输入模式&#xff0c;表示DE2-115开发板上的18个…

大历史下的 tcp:一个松弛的传输协议

如果 tcp 是一个相对松弛的协议&#xff0c;会发生什么。 所谓松弛感&#xff0c;意思是它允许 “漏洞”&#xff0c;允许可靠传输的不封闭&#xff0c;大致就是&#xff1a;“不求 100% 可靠&#xff0c;只要 90%(或多或少) 可靠&#xff0c;另外 10% 的错误可检测到” or “…

分享三维地理模型制作实践

前言 地理信息系统&#xff08;GIS&#xff09;是一种用于捕获、存储、检查和显示与地球表面位置相关的数据的计算机系统。GIS可以在一张地图上显示许多不同类型的数据&#xff0c;如街道、建筑物和植被。这使人们能够更容易地看到、分析和理解模式和关系。 实践 从地理空间…

SinoDB数据库的RAW TABLE

RAW表是不记录日志的永久表&#xff0c;类似于无日志模式数据库中的表。对于RAW表&#xff0c;支持对其进行更新、插入和删除操作&#xff0c;但日志是不会记录这些操作。可以在RAW表上定义索引&#xff0c;但不能在RAW表上定义唯一约束、主键约束或引用约束&#xff08;refere…

艺术的新领域——探索元宇宙艺术展带来的沉浸式艺术体验

在数字化的浪潮中&#xff0c;元宇宙艺术展成为了一种全新的展览形式&#xff0c;它通过虚拟现实、3D建模技术和互动平台&#xff0c;将传统艺术与现代科技巧妙结合&#xff0c;提供了一种前所未有的艺术欣赏方式。此类展览不仅展示了艺术作品的新颖呈现&#xff0c;还为参观者…

在数字化转型的浪潮中,CBDB百数服务商如何破浪前行?

在信息化时代&#xff0c;传统咨询企业面临着数字化转型的挑战与机遇。如何利用数字化技术提升业务效率、增强客户黏性&#xff0c;成为了行业关注的焦点。云南析比迪彼企业管理有限公司&#xff08;CBDB&#xff09;作为云南地区的企业咨询服务提供商&#xff0c;率先与百数展…

卷价格不如卷工艺降本增效狠抓模块规范化设计

俗话说&#xff0c;“卷价格不如卷工艺”&#xff0c;这意味着在追求成本控制和效率提升的过程中&#xff0c;蓝鹏的领导认为蓝鹏应该更注重工艺的优化和创新&#xff0c;而不仅仅是价格的竞争。而模块规范化设计正是实现这一目标的有效途径。 模块规范化设计可以提高生产效率…

java代码运行“找不到符号”报错解决?

查看maven配置&#xff0c;没有问题&#xff1a; 查看pom依赖配置&#xff0c;发现少了spring-boot依赖项&#xff1a; 原pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:…

【超好用的前端表单辅助功能】

前端表单辅助功能 1. 根据模块自动生成目录锚点定位2. 描点定位动态组件3. 隔离组件&#xff0c;组件内部实现校验逻辑&#xff0c;交给提交按钮统一处理4. 选择不同的类型需要重组不同的模块展示&#xff0c;并整合数据传给后端 最近做了一个复杂的表单&#xff0c;涉及到的技…

链表成环或多分枝问题

问题概述 这类问题主要和数论结合到一起。 这类问题主要的解决技巧就是画图&#xff0c;跟着图来写代码&#xff0c;不然代码5分钟&#xff0c;调试2小时。 因为每个节点可以指向下一个节点&#xff0c;那么两个节点就可以指向同一个节点&#xff1b;或者链表的末尾节点指向…

SIC知识(9)--长晶炉的技术难点

长晶炉是碳化硅晶体生长的核心设备&#xff0c;与传统晶硅级长晶炉有相同性&#xff0c;炉子结构不是非常复杂&#xff0c;主要由炉体、加热系统、线圈传动机构、真空获得及测量系统、气路系统、降温系统、控制系统等组成&#xff0c;其中的热场和工艺条件决定了碳化硅晶体的质…

多微信管理不过来?你需要一个微信神器

很多企业都在面临以下几个问题&#xff1a; 1、希望进行微信营销转型&#xff0c;但是不知道如何入手&#xff1b; 2、拥有多个微信号&#xff0c;但不想拿着多台手机&#xff0c;希望能够集中管理所有微信号&#xff1b; 3、希望使用app替代传统的营销体系&#xff0c;并确…

【Flutter】App内购支付集成 Google和Apple支付和服务器验证全流程

Flutter支付集成 前言&#xff1a; 以谷歌内购为例&#xff0c;我们需要做的总共为三步 需要在谷歌市场配置商品&#xff0c;设置测试渠道&#xff0c;配置开发者账号&#xff0c;设置对应权限。配置完商品之后&#xff0c;如何在 Flutter 中获取到商品&#xff0c;购买指定…

Leetcode—377. 组合总和 Ⅳ【中等】

2024每日刷题&#xff08;124&#xff09; Leetcode—377. 组合总和 Ⅳ 算法思想 实现代码 class Solution { public:int combinationSum4(vector<int>& nums, int target) {vector<unsigned long long>dp(target 1);dp[0] 1;for(int i 1; i < target;…