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

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

目录

  • 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.mzph.cn/bicheng/7208.shtml

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

相关文章

商城数据库88张表结构完整示意图81~88及总览图(十六)

八十一&#xff1a; 八十二&#xff1a; 八十三&#xff1a; 八十四&#xff1a; 八十五&#xff1a; 八十六&#xff1a; 八十七&#xff1a; 八十八&#xff1a; 总览图&#xff1a;

Redis开源社区持续壮大,华为云为Valkey项目注入新的活力

背景 今年3月21日&#xff0c;Redis Labs宣布从Redis 7.4版本开始&#xff0c;将原先比较宽松的BSD源码使用协议修改为RSAv2和SSPLv1协议&#xff0c;意味着 Redis在OSI&#xff08;开放源代码促进会&#xff09;定义下不再是严格的开源产品。Redis官方表示&#xff0c;开发者…

websevere服务器从零搭建到上线(四)|muduo网络库的基本原理和使用

文章目录 muduo源码编译安装muduo框架讲解muduo库编写服务器代码示例代码解析用户连接的创建和断开回调函数用户读写事件回调 使用vscode编译程序配置c_cpp_properties.json配置tasks.json配置launch.json编译 总结 muduo源码编译安装 muduo依赖Boost库&#xff0c;所以我们应…

webpack与vite

webpack 使用步骤&#xff1a; 初始化项目 pnpm init -y安装依赖webpack、webpack-cli在项目中创建src目录&#xff0c;然后编写代码&#xff08;index.js&#xff09;执行pnpm weboack来对代码进行打包&#xff08;打包后观察dist文件夹&#xff09; 配置古文件&#xff08;w…

使用ThemeRoller快速实现前端页面风格美化

使用ThemeRoller快速实现前端页面风格美化 文章目录 使用ThemeRoller快速实现前端页面风格美化一、ThemeRoller二、使用方法1.基本操作面板介绍2.直接用现成的配色风格——Gallery画廊3.自定义风格——Roll Your Own4.下载风格包并应用到页面 一、ThemeRoller ThemeRoller是jQ…

基于java的CRM客户关系管理系统的设计与实现(论文 + 源码 )

【免费】基于Java的CRM客户关系管理系统的设计和实现.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89273409 基于Java的CRM客户关系管理系统的设计与实现 摘 要 随着互联网的高速发展&#xff0c;市场经济的信息化&#xff0c;让企业之间的竞争变得&#xff0…

纯血鸿蒙APP实战开发——页面间共享组件实例的案例

介绍 本示例提供组件实例在页面间共享的解决方案&#xff1a;通过Stack容器&#xff0c;下层放地图组件&#xff0c;上层放Navigation组件来管理页面&#xff0c;页面可以共享下层的地图组件&#xff0c;页面中需要显示地图的区域设置为透明&#xff0c;并参考触摸交互控制&am…

各城市-人口就业和工资数据(1978-2022年)

这份数据收集了1978年至2022年间300多个地级市的人口、就业和工资等数据。涵盖的指标包括从业人员数量、平均工资水平、人口密度等&#xff0c;通过这些数据可以深入了解中国各地城市的人口结构、就业状况以及工资水平的变化趋势。这些数据对于研究城市发展、劳动力市场以及区域…

论文架构介绍

论文架构 背景&#xff1a;建议2段左右完成&#xff0c;字数控制在500左右为佳&#xff0c;对应子题目1过渡段&#xff1a;写150字左右的过渡段&#xff0c;承上启下&#xff0c;回答部分子题目2、3的要求正文实践部分&#xff1a;一般3-7个论点&#xff0c;根据题目的要求来看…

C++构造函数和析构函数的调用顺序

一般情况下&#xff0c;调用析构函数的次序正好与调用构造函数的次序相反&#xff0c;也就是最先被调用的构造函数&#xff0c;其对应的析构函数最后被调用&#xff0c;而最后被调用的构造函数&#xff0c;其对应的析构函数最先被调用。 当然对象的构造函数和析构函数调用时机和…

力扣100284. 有效单词(C++)

【题解】 (实际在力扣中运行的代码只需要把下方的check函数放到力扣作答区给的模板中就可以) #include <bits/stdc.h> #include <iostream> #include <vector> #include <string> #include <cctype> #include <cstring> #include <st…

融知财经:期货交易的规则和操作方法

期货交易是指在未来的某一特定时期&#xff0c;买卖双方通过签订合约的方式&#xff0c;约定以某种价格买卖一定数量的某种商品或资产的行为。期货交易的规则和操作方法如下&#xff1a; 期货交易的规则和操作方法 1、双向交易&#xff1a; 期货市场允许投资者进行多头&#xf…

Python ArcPy批量将大量栅格文件的投影坐标系转为地理坐标系

本文介绍基于Python语言中的ArcPy模块&#xff0c;批量将多个遥感影像由投影坐标系转为地理坐标系的方法。 在之前的文章中&#xff0c;我们介绍过将单独1景遥感影像的投影坐标系转为地理坐标系的方法&#xff0c;大家可以参考文章投影坐标系转为地理坐标系&#xff1a;GDAL命令…

笔记86:关于【#ifndef + #define + #endif】的用法

当你在编写一个头文件&#xff08;例如 pid_controller.h&#xff09;时&#xff0c;你可能会在多个源文件中包含它&#xff0c;以便在这些源文件中使用该头文件定义的函数、类或其他声明。如果你在多个源文件中都包含了同一个头文件&#xff0c;那么当你将整个工程统一编译&am…

第六节课《Lagent AgentLego 智能体应用搭建》

PDF链接&#xff1a;https://pan.baidu.com/s/1JFtvBWgEGFWJq8pHafvIUg?pwd6666 提取码&#xff1a;6666 Lagent & AgentLego 智能体应用搭建_哔哩哔哩_bilibili https://github.com/InternLM/Tutorial/blob/camp2/agent/README.md InternStudio 一、为什么需要agent…

基于JSP的酒店客房管理系统(三)

目录 第四章 系统各模块的实现 4.1客房管理系统首页的实现 4.1.1 客房管理系统首页概述 4.2客房管理系统前台的实现 4.2.1 客房管理系统前台概述 4.2.2 客房管理系统前台实现过程 4.2.3 预定客房信息及客房信息的查询 4.3客房管理系统后台的实现 4.3.1 客房管理系统后…

微搭低代码入门05文件的上传和下载

目录 1 创建数据源2 创建应用3 创建页面4 设置导航功能5 文件上传6 文件下载总结 小程序中&#xff0c;我们通常会有文件的上传和下载的需&#xff0c;在微搭中&#xff0c;文件是存放在云存储中&#xff0c;每一个文件都会有一个唯一的fileid&#xff0c;我们本篇就介绍如何通…

Unity类银河恶魔城学习记录 17-1,2 p166 Aliments fx p167 Blackhole additional vfx

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Entity.cs using System.Collections; using System.Collections.Generic; …

Vue3(管理系统)-封装axios(utils)

一、在utils下编写request.js实例 1.添加基地址&#xff0c;设置超时时间 import axios from axios const baseURL http://big-event-vue-api-t.itheima.net const instance axios.create({// TODO 1. 基础地址&#xff0c;超时时间baseURL,timeout: 3000 }) 2.添加请求拦截…

[C++][数据结构]红黑树的介绍和模拟实现

前言 之前我们简单学习了一下搜索树和平衡搜索树&#xff0c;今天我们来学习一下红黑树 简介 概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着…