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

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

目录

  • 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.mfbz.cn/a/596732.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2.5W字 一文读懂汽车智能座舱的FLASH 存储市场、技术

吃瓜群众&#xff1a;机哥&#xff0c;存储是什么玩意&#xff0c;我买手机、电脑的时候导购员都说买内存大的&#xff0c;三星的好&#xff0c;品牌大&#xff0c;问题少&#xff0c;我也只有看哪个内存大就买那个。 机哥&#xff1a;额&#xff0c;这个嘛&#xff0c;说来话长…

设计模式之建造者模式BuilderPattern(七)

一、建造者模式 建造者模式&#xff08;Builder Pattern&#xff09;使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 二、代码实例 1、OrderItem类 Data&#xff1a;这是Lombok中提供的Ge…

淡茶和浓茶的标准

按照《品深淡茶冲泡标准》&#xff0c;淡茶茶汤中的咖啡碱不得高于31.67mg/100mL&#xff0c;可可碱不得高于2.67mg/mL&#xff0c;茶碱不得高于1.50mg/100mL&#xff0c;茶多酚不得高于143mg/mL&#xff0c;按照各类茶叶中各物质的含量情况&#xff0c;茶水比例不得高于1:150&…

一个JDBC小工具

pom.xml 结构 <properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><mysql5>5.1.44<…

CellMarker | 人骨骼肌组织细胞Marker大全!~(强烈建议火速收藏!)

1写在前面 分享一下最近看到的2篇paper关于骨骼肌组织的细胞Marker&#xff0c;绝对的Atlas级好东西。&#x1f44d; 希望做单细胞的小伙伴觉得有用哦。&#x1f60f; 2常用marker&#xff08;一&#xff09; general_mrkrs <- c( MYH7, TNNT1, TNNT3, MYH1, MYH2, "C…

文心一言 VS 讯飞星火 VS chatgpt (253)-- 算法导论18.2 6题

六、假设 B-TREE-SEARCH 的实现是在每个结点内采用二分查找&#xff0c;而不是线性查找。证明&#xff1a;无论怎样选择 t ( t 为 n 的函数)&#xff0c;这种实现所需的 CPU 时间都为 O(lgn)。如果要写代码&#xff0c;请用go语言。 文心一言&#xff1a; 首先&#xff0c;我…

tkinter/python:第一个GUI程序——制作一个数据录入界面

下图是在网上搜寻的一个案例图样&#xff0c;经过了调整修改&#xff0c;登录时界面图如下&#xff1a; 登录后点击百货店铺按钮&#xff0c;界面如下 一、创建root窗口&#xff1a; geometry接收一个字符串&#xff0c;也就是需要建立的窗口尺寸和位置&#xff0c;geometry(…

【Osek网络管理测试】[TG3_TC6]等待总线睡眠状态_2

&#x1f64b;‍♂️ 【Osek网络管理测试】系列&#x1f481;‍♂️点击跳转 文章目录 1.环境搭建2.测试目的3.测试步骤4.预期结果5.测试结果 1.环境搭建 硬件&#xff1a;VN1630 软件&#xff1a;CANoe 2.测试目的 验证DUT在满足进入等待睡眠状态的条件时是否进入该状态 …

Vue 基础语法

【1】模板语法 &#xff08;1&#xff09;差值表达式 {{}}是 Vue.js 中的文本插值表达式。 它用于在模板中输出数据或表达式的值。当数据或表达式的值发生变化时&#xff0c;插值表达式会自动更新。 补充&#xff1a;三目运算符 它的基本语法是 Condition ? A : B&#xff0…

解密SSL/TLS:密码套件扫描仪的深度解析(C/C++代码实现)

解密SSL/TLS流量通常是为了分析和审计加密通信&#xff0c;以确保数据传输的安全性和合规性。密码套件扫描仪是实现这一目的的一种工具&#xff0c;它可以提供关于SSL/TLS配置的详细信息&#xff0c;帮助安全专家评估潜在的风险。 SSL/TLS协议基础 SSL/TLS协议是网络安全中不…

Redis探索之旅(基础)

目录 今日良言&#xff1a;满怀憧憬&#xff0c;阔步向前 一、基础命令 1.1 通用命令 1.2 五大基本类型的命令 1.2.1 String 1.2.2 Hash 1.2.3 List 1.2.4 Set 1.2.5 Zset 二、过期策略以及单线程模型 2.1 过期策略 2.2 单线程模型 2.3 Redis 效率为什么这么高 三…

AI人才争夺战,华尔街入局:豪掷百万美元年薪抢人 | 最新快讯

量子位公众号 QbitAI 继硅谷之后&#xff0c;华尔街也入局“AI 人才争夺大战”。 他们的目标非常明确——抢的就是高精尖的 AI 专家。 △图源&#xff1a;Business Insider 现在这条“街”上&#xff0c;不论是银行、对冲基金还是私募股权公司都已纷纷下场&#xff0c;可谓是豪…

(读书笔记-大模型) LLM Powered Autonomous Agents

目录 智能体系统的概念 规划组件 记忆组件 工具组件 案例研究 智能体系统的概念 在大语言模型&#xff08;LLM&#xff09;赋能的自主智能体系统中&#xff0c;LLM 充当了智能体的大脑&#xff0c;其三个关键组件分别如下&#xff1a; 首先是规划&#xff0c;它又分为以下…

2024第六届人工智能与教育国际研讨会(WAIE 2024)即将召开!

2024第六届人工智能与教育国际研讨会&#xff08;WAIE 2024&#xff09;将于2024年9月28-30日在日本东京举行。WAIE 2024的召开&#xff0c;旨在汇聚全球智慧&#xff0c;共同探讨人工智能在教育领域的应用与发展&#xff0c;找到人工智能与教育融合发展的最佳路径&#xff0c;…

从零开始的软件测试学习之旅(五)web测试项目

这里写目录标题 功能型测试非功能性测试面试拓展项目与数据库关系 测试用例设计—基于TPshop前台下单流程 功能型测试 一.设计测试 a,需求分析 1.输入分析 分析项目中要求如:输入长度,类型要求,组成规则,是否为空,是否重复 2.交付分析 判断所有数据正确,有错误给出提示(优化…

i.MX 6ULL 裸机 IAR 环境安装

一. IAR 的安装请自行搜索 二. 使用最新版本的 IAR&#xff0c;需要修改 SDK 1. 在 SDK 的 core_ca7.h 加上 #include "intrinsics.h" /* IAR Intrinsics */ 2. debug 时需要修改每个工程下的 ddr_init.jlinkscript&#xff0c;参考链接 Solved: How to conn…

双重检验锁方式实现单例模式

单例模式&#xff08;Singleton Pattern&#xff09;&#xff1a;是指在内存中只会创建且仅创建一次对象的设计模式。在程序中多次使用同一个对象且作用相同时&#xff0c;为了防止频繁地创建对象使得内存飙升&#xff0c;单例模式可以让程序仅在内存中创建一个对象&#xff0c…

电源小白入门学习7——USB充电、供电、电源路径管理

电源小白入门学习7——USB充电、供电、电源路径管理 USB充电系统需要考虑的因素开关充电和线性充电充电路径管理输入限流路径管理&#xff08;动态功率管理&#xff09;理想二极管帮助提高电池利用率输入过充抑制 上期我们介绍了锂离子电池的电池特性&#xff0c;及充电电路设计…

OpenNJet评测,探寻云原生之美

在信息时代的大海上&#xff0c;云原生应用引擎如一艘航行于波涛之间的帆船&#xff0c;承载着创新的梦想和数字化的未来。本文将带领您登上这艘船&#xff0c;聚焦其中之一的OpenNJet&#xff0c;一同探寻其中的奥秘和精妙&#xff0c;领略其独特之美。 OpenNJet 内容浅析 O…

【JavaScript】数据类型转换

JavaScript 中的数据类型转换主要包括两种&#xff1a;隐式类型转换&#xff08;Implicit Type Conversion&#xff09;和显式类型转换&#xff08;Explicit Type Conversion&#xff09;。 1. 隐式类型转换&#xff08;自动转换&#xff09;&#xff1a; js 是动态语言&…