【滑动窗口】leetcode209:长度最小的子数组

一.题目描述

长度最小的子数组

 二.思路分析

题目要求:找出长度最小的符合要求的连续子数组,这个要求就是子数组的元素之和大于等于target。

如何确定一个连续的子数组?确定它的左右边界即可。如此一来,我们最先想到的就是暴力枚举,枚举所有的子数组,找到符合要求的,比较出长度最短的那一个。

class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int n = nums.size();int ret = INT_MAX;for (int left = 0; left < n; left++){int sum = 0;for (int right = left; right < n; right++){sum += nums[right];if (sum >= target){ret = min(ret, right - left + 1);}}}return ret == INT_MAX ? 0 : ret;}
};

两层for循环,时间复杂度O(n^2),leetcode上运行超时,我们需要想办法优化时间复杂度。

时间复杂度这么高就是因为做了大量的枚举,我们是否有办法减少一些不必要的枚举呢?

key1

以这个测试用例为例,当right从left位置一直向右移动到该位置,区间之和满足要求,记录此时的长度4并更新结果。

按照暴力枚举的策略right还要继续向后移动。但我们知道,后面的区间肯定也是满足条件的,因为所有的数都是正整数,sum只会越加越大。

即便如此,区间长度肯定也会更大,所以此时就是left固定在第一个位置的局部最优解,right不必再向后枚举了。

key2

left向右移动一个单位,按照暴力枚举策略,right要从图中的标记处回退到left位置 

但我们知道right最终还是会一直往前走,到达原先的标记处。为啥呢?通过上一轮枚举结果,我们已知[left - 1 , tmp)区间是不满足要求的,更别说现在还少了一个数。

所以right没有必要退回去,因为退了也是白退。

key3

所以left前进即可,right不用后退。怎么计算此时区间长度和呢?遍历一遍区间吗?那right岂不是还要回去?其实只需要在left移动之前用sum减去left指向的值即可,然后再移动left。

按照图中的实例,此时不满足条件,所以right继续向后移动,又回到了之前的逻辑。

如果此时满足条件呢?那么这个就是left固定在这个位置的局部最优解了,更新结果之后,left继续向右移动。

故left可能会向后移动多步,所以要用循环实现。

三.代码实现

在代码实现过程中,我们需要用到两个指针(下标)来标记左边界和右边界。通过分析,left和right只会向前移动而不会后退,就像一个窗口一样从左到右划过数组故形象的将这类方法称为滑动窗口,也叫同向双指针。当研究对象是一个连续区间时,并且证明left和right都不用后退时便可以考虑使用滑动窗口解题。

 滑动窗口类题目常见就这几个步骤,先定义两个指针,然后right指向的元素进窗口,判断条件,决定是否出窗口,有时可能需要出多个元素,所以此处可能是一个循环过程,例如本题就是。至于更新结果要根据具体的题目来确定位置,有可能是进窗口以后,又有可能是出窗口之前,还可能是出窗口之后。

整个过程是循环的,当right越界时也就结束了。

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

 最坏的情况就是right和left都走到了末尾,相当于两个指针都遍历一遍数组,时间复杂度为O(n)

 

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

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

相关文章

Linux 多线程基础

文章目录 前言一、多线程基础函数1. pthread_create2. pthread_self3. pthread_exit4. pthread_join5. pthread_cancel6. pthread_detach 二、线程间的共享数据三、多线程 &#xff0c;进程对比总结 前言 一、多线程基础函数 1. pthread_create 创建新的线程。 #include <…

使用EventLog Analyzer 进行路由器监控

路由器是任何计算机网络的构建块&#xff0c;引导网络中的流量&#xff0c;管理员需要确保路由器已配置并正常工作&#xff0c;以确保网络安全。 监控路由器中的用户活动 在网络安全方面&#xff0c;与路由器相关的风险是一个严重的问题。具有松散安全策略的网络使入侵者可以…

kafka--技术文档--基本docker中安装<单机>-linux

安装zookeeper 阿丹小科普&#xff1a; Kafka在0.11.0.0版本之后不再依赖Zookeeper&#xff0c;而是使用基于Raft协议的Kafka自身的仲裁机制来替代Zookeeper。具体来说&#xff0c;Kafka 2.8.0版本是第一个不需要Zookeeper就可以运行Kafka的版本&#xff0c;这被称为Kafka Raf…

3 自制一个集群分发脚本

1. 随便取了一个名字&#xff1a;xsync 2. 在一个配置环境变量的目录下&#xff0c;我是放在了/opt/software下&#xff0c;这个路径我是配置了环境变量的。 3. 编辑脚本&#xff1a;vim xsync #!/bin/bash#1. 判断参数个数 if [ $# -lt 1 ] thenecho Not Enough Arguement!…

【⑮MySQL | 视图】概述 | 创建 | 查看 | 更新 | 修改 | 删除

前言 ✨欢迎来到小K的MySQL专栏&#xff0c;本节将为大家带来MySQL视图概述 | 创建 | 查看 | 更新 | 修改 | 删除的分享✨ 目录 前言1.视图概述2.创建视图3.查看视图4.更新视图数据5.修改视图6.删除视图总结 1.视图概述 1.1 为什么使用视图&#xff1f; 视图一方面可以帮我们使…

如何构建多域名HTTPS代理服务器转发

在当今互联网时代&#xff0c;安全可靠的网络访问是至关重要的。本文将介绍如何使用SNI Routing技术来构建多域名HTTPS代理服务器转发&#xff0c;轻松实现多域名的安全访问和数据传输。 SNI代表"Server Name Indication"&#xff0c;是TLS协议的扩展&#xff0c;用于…

2023年国赛 高教社杯数学建模思路 - 案例:随机森林

文章目录 1 什么是随机森林&#xff1f;2 随机深林构造流程3 随机森林的优缺点3.1 优点3.2 缺点 4 随机深林算法实现 建模资料 ## 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 什么是随机森林&#xff…

数据结构(Java实现)-二叉树(下)

获取二叉树的高度 检测值为value的元素是否存在(前序遍历) 层序遍历 判断一棵树是不是完全二叉树 获取节点的路径 二叉树的最近公共祖先

Docker基本部署和相关操作

1.安装docker服务&#xff0c;配置镜像加速器 1、yum安装并且添加源信息 yum install yum-utils device-mapper-persistent-data lvm2 -y yum-config-manager --add-repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo2、修改一些配置信息 sed…

Kaggle回归问题Mercedes——Benz Greener Manufacturing

目录 前言1 题目介绍2 数据清洗3 数据可视化分析4 模型训练5 源码 前言 这是我在大三选修课的课程设计&#xff0c;内容参考了Kaggle上高赞的代码&#xff0c;有详细批注&#xff0c;整体比较基础&#xff0c;结构相对完整&#xff0c;便于初学者学习。这个是一个回归问题&…

⌈算法进阶⌋图论::拓扑排序(Topological Sorting)——快速理解到熟练运用

目录 一、原理 1. 引例&#xff1a;207.课程表 2. 应用场景 3. 代码思路 二、代码模板 三、练习 1、210.课程表Ⅱ&#x1f7e2; 2、2392.给定条件下构造举证&#x1f7e1; 3、310.最小高度树 &#x1f7e1; 一、原理 1. 引例&#xff1a;207.课程表 就如大学课程安排一样&…

21.2 CSS 三大特性与页面布局

1. 开发者工具修改样式 使用开发者工具修改样式, 操作步骤如下: * 1. 打开开发者工具: 在浏览器中右键点击页面, 然后选择检查或者使用快捷键(一般是 F12 或者 CtrlShiftI)来打开开发者工具.* 2. 打开样式编辑器: 在开发者工具中, 找到选项卡或面板, 一般是Elements或者Elemen…

【Go Web 篇】从零开始:构建最简单的 Go 语言 Web 服务器

随着互联网的迅速发展&#xff0c;Web 服务器成为了连接世界的关键组件之一。而在现代编程语言中&#xff0c;Go 语言因其卓越的性能和并发能力而备受青睐。本篇博客将带你从零开始&#xff0c;一步步构建最简单的 Go 语言 Web 服务器&#xff0c;让你对 Go 语言的 Web 开发能力…

线性代数的学习和整理14: 线性方程组求解

目录 1 线性方程组 2 有解&#xff0c;无解 3 解的个数 1 线性方程组 A*xy 3根直线的交点&#xff0c;就是解 无解的情况 无解&#xff1a; 三线平行无解&#xff1a;三线不相交 有解 有唯一解&#xff1a;三线相交于一点有无数解&#xff1a;三条线重叠 2 齐次线性方程组…

Vue的使用

Vue的使用 Vue到底是啥&#xff1f;Vue中包含了两部分虚拟DOM 模块化编程虚拟DOM&#xff0c;在我们重用模板的时候&#xff0c;在Vue中存在虚拟DOM 虚拟DOM是为了更好的去重用我们的DOM (增加元素的时候&#xff0c;先去虚拟DOM找是否存在&#xff0c;如果有那么不用生成&am…

VUE笔记(六)vue路由

一、路由的简介 1、实现生活中的路由 路由&#xff1a;路由其实就是一个key-value对应关系 路由器&#xff1a;用于管理多个路由关系的设备被称为路由器 2、前端的路由 目前使用的前端项目都是单页面的应用&#xff08;SPA&#xff09;&#xff0c;一个项目中只有一个html页…

c语言中编译过程与预处理

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、c语言的编译与链接1、编译与链接概述2、编译与链接详解 二、c语言预处理1.c语言中内置的预定义符号2、#define定义标识符3、#define定义宏4、#define 替换规…

CSS scoped 属性的原理

scoped 一、scoped 是什么&#xff1f;二、实现原理 一、scoped 是什么&#xff1f; 在 Vue 组件中&#xff0c;为了使样式私有化&#xff08;模块化&#xff09;&#xff0c;不对全局造成污染&#xff0c;可以在 style 标签上添加 scoped 属性以表示它的只属于当下的模块&am…

数组和指针练习解析(6)

题目&#xff1a; int main() { char *c[] {"ENTER","NEW","POINT","FIRST"}; char**cp[] {c3,c2,c1,c}; char***cpp cp; printf("%s\n", **cpp); printf("%s\n", *--*cpp3)&#xff1b; printf("%s\n&…

数据结构(Java实现)-包装类和泛型

包装类 在Java中&#xff0c;由于基本类型不是继承自Object&#xff0c;为了在泛型代码中可以支持基本类型&#xff0c;Java给每个基本类型都对应了 一个包装类型。 基本数据类型和对应的包装类 装箱和拆箱 装箱操作&#xff0c;新建一个 Integer 类型对象&#xff0c;将 i 的…