算法练习-长度最小的子数组(思路+流程图+代码)

难度参考

        难度:简单

        分类:数组

        难度与分类由我所参与的培训课程提供,但需要注意的是,难度与分类仅供参考。以下内容均为个人笔记,旨在督促自己认真学习。

题目

        给定一个含有个正整数的数组和一个正整数s,找出该数组中满足其和≥s的长度最小的连续子数组,并返回其长度。如果不存在符合条件的子数组,返回0。

        示例1:

        输入:s=7,
                   nums=[2,3,1,2,4,3]
        输出:2
        解释:子数组[4,3]是该条件下的长度最小的子数组。

思路

暴力做法

        使用暴力法解决这道题的思路是遍历所有可能的连续子数组,计算它们的和,并找到满足条件的最小子数组长度。以下是暴力法的详细题解:

  1. 初始化一些变量,包括最小长度 minLength 初始为正无穷大。

  2. 使用两层循环,外层循环以每个元素为起点,内层循环遍历从该起点开始的子数组。外层循环变量 start 从0开始,内层循环变量 endstart 开始。

  3. 在内层循环中,计算子数组的和 sum,即从 nums[start]nums[end] 的元素的累加和。

  4. 如果 sum 大于或等于目标值 s,说明当前子数组的和满足条件,可以记录下当前子数组的长度 end - start + 1

  5. 在外层循环中,不断更新 minLength,即记录当前满足条件的子数组的最小长度。

  6. 继续外层循环,直到遍历完整个数组。

  7. 最后,如果 minLength 没有被更新过,说明没有满足条件的子数组,返回0;否则,返回 minLength

        这个算法的核心思想是遍历所有可能的子数组,计算它们的和并比较长度,找到最小长度的满足条件的子数组。由于使用了两层循环,时间复杂度是O(n^2),其中n是数组的长度。这个算法虽然不如滑动窗口法高效,但是可以解决问题。

        暴力做法不再提供示例与梳理,感觉可以直接看代码。

滑动窗口

        可以使用滑动窗口的方法解决这个问题。滑动窗口是维护一个连续子数组的常用技巧,通过左指针和右指针来移动窗口,根据窗口内元素的和来调整窗口的大小。具体步骤如下:

  1. 初始化左指针 left 为0,右指针 right 为0,以及窗口内元素的和 sum 为0。

  2. 使用右指针 right 向右遍历数组,不断将元素添加到窗口内,并更新 sum

  3. sum 大于等于给定的正整数 s 时,记录当前窗口的长度 right - left + 1

  4. 缩小窗口,即左指针 left 向右移动,同时从 sum 中减去左边界的元素,直到 sum 小于 s

  5. 重复步骤2到4,直到遍历完整个数组。

  6. 在整个过程中,不断更新最小子数组的长度,最终得到最小长度。

通过滑动窗口找到最小长度的连续子数组,时间复杂度为O(n),其中n是数组的长度。

示例

        理解滑动窗口算法可能有点抽象,让我尝试以更简单的方式解释它。

        简单解释:

        滑动窗口算法就像你在一堆连续的数字中寻找一个连续的子集,这个子集的和大于等于给定的值s,而且这个子集的长度要尽可能小。

        首先,你从数组的开头找到一个子集,看它的和是否满足条件。如果和小于s,你就继续扩大子集,添加更多的数字。如果和大于等于s,你记录下这个子集的长度。

        接下来,你缩小子集的范围,从左边开始移除数字,然后再检查新的子集是否满足条件。如果满足,你再次记录子集的长度,然后继续缩小范围。

        你不断地重复这个过程,直到遍历完整个数组。最终,你会找到一个满足条件的子集,它的长度是最小的。

        这就是滑动窗口算法的核心思想:不断调整子集的范围,以找到满足条件的最小子集。

        让我们使用一个示例来说明滑动窗口算法的工作方式:

        示例:

        假设有一个数组 nums,其内容如下:

nums = [2, 3, 1, 2, 4, 3]

        我们的目标是找到一个连续的子数组,该子数组的和大于等于7,并且长度尽可能小。

        步骤1:初始化窗口

        我们从左到右遍历数组,初始化左指针 left 和右指针 right,以及窗口内的和 sum

left = 0, right = 0, sum = 0

        步骤2:扩展窗口

        我们开始扩展窗口,将右指针 right 向右移动,逐个添加元素,并更新 sum 的值。我们的目标是找到一个子数组,其和大于等于7。

left = 0, right = 0, sum = 2 
left = 0, right = 1, sum = 5 
left = 0, right = 2, sum = 6 
left = 0, right = 3, sum = 8

        在这个过程中,当 sum 大于等于7时,我们记录下当前窗口的长度(right - left + 1),并且这是我们找到的目前最小的长度。

        步骤3:缩小窗口

        接下来,我们需要缩小窗口,即将左指针 left 向右移动,同时从 sum 中减去左边界的元素。我们不断缩小窗口,以尝试找到更小的子数组。

left = 1, right = 3, sum = 7

        在这一步,我们找到了一个和为7的子数组,长度为3,这是目前找到的最小长度。

        步骤4:继续寻找

        然后,我们继续向右移动右指针 right,并尝试寻找更小的子数组。

left = 1, right = 4, sum = 11

        在这一步,我们找到了一个和为11的子数组,长度为4。

        步骤5:缩小窗口

        接着,我们再次缩小窗口,继续寻找更小的子数组。

left = 2, right = 4, sum = 9

        在这一步,我们找到了一个和为9的子数组,长度为3。

        步骤6:继续寻找

        我们继续向右移动右指针 right,寻找更小的子数组。

left = 2, right = 5, sum = 12

        在这一步,我们找到了一个和为12的子数组,长度为4。

        步骤7:缩小窗口

        最后,我们再次缩小窗口。

left = 3, right = 5, sum = 10

        在这一步,我们找到了一个和为10的子数组,长度为3。

        图示:      

        2+3+1+2=8>7(找出该数组中满足其和≥s的长度),第一次更新滑动窗口长度。

        尝试缩小窗口(移动左指针),发现3+1+2=6<7。

        因此,继续寻找(移动右指针),调整窗口(1+2+4>7),第二次更新滑动窗口长度。

        同理,在尝试缩小窗口(移动左指针【先】)与继续寻找(移动右指针【后】)之后,调整窗口(1+2+4>7),第三次更新滑动窗口长度。

        尝试缩小窗口(移动左指针),发现4+3>=7,第四次更新滑动窗口长度。

        尝试缩小窗口(移动左指针),发现3<7, 继续寻找(移动右指针), 右指针 j > 数组长度,结束循环。我们就得到了所需要的窗口长度(即该数组中满足其和≥s的长度最小的连续子数组的长度)。

        结果:

        在整个过程中,我们不断调整窗口的大小,以找到和大于等于7的最小子数组。最终,我们找到了一个和为7的子数组,长度为2。这是我们要找的答案。

        所以,滑动窗口算法的结果是2,表示最小连续子数组的长度为2,即子数组 [4, 3]

梳理

        滑动窗口算法之所以能够实现找到满足条件的最小连续子数组,是因为它巧妙地利用了窗口的概念,通过不断调整窗口的大小和位置,来搜索满足条件的最小子数组。以下是为什么这个算法能够实现的原因:

  1. 窗口的左右边界移动: 算法使用两个指针,一个左指针和一个右指针,它们分别表示当前窗口的左边界和右边界。通过不断移动这两个指针,算法模拟了不同窗口的情况。

  2. 窗口内元素和的计算: 算法维护一个变量 sum,用于记录当前窗口内元素的和。随着右指针的移动,不断将新元素添加到窗口内,并更新 sum。这使得算法能够动态地计算窗口内元素的和。

  3. 根据和的大小调整窗口: 在每一步中,算法检查 sum 是否满足给定的条件(例如,是否大于等于s)。如果满足条件,算法会记录当前窗口的长度,然后尝试缩小窗口,即移动左指针。如果不满足条件,算法会继续扩大窗口,即移动右指针。

  4. 不断更新最小长度: 算法在整个过程中不断记录最小的子数组长度。每当找到一个满足条件的子数组时,它会与之前记录的最小长度比较,然后更新最小长度。这确保了算法找到的是最小的满足条件的子数组。

  5. 遍历整个数组: 算法通过不断移动右指针,遍历整个数组,以寻找满足条件的子数组。因为算法考虑了数组中的每个元素,所以它能够找到所有可能的子数组,从中选择最小长度的子数组。

        总结来说,滑动窗口算法通过动态地维护一个窗口,根据窗口内元素和的大小来调整窗口的位置和大小,从而找到满足条件的最小子数组。它的核心思想是不断地搜索可能的子数组,然后选择最小长度的子数组作为答案。这个算法的时间复杂度为O(n),因为每个元素最多被访问两次(一次添加到窗口,一次从窗口移除),其中n是数组的长度。

代码

暴力做法

#include <iostream>
#include <vector>
#include <climits> // 包含 <climits> 头文件以引入 INT_MAX

using namespace std;

// 定义一个函数,找到满足和≥s的最短连续子数组的长度(暴力法)
int minSubArrayLen(int s, vector<int>& nums) {
    int n = nums.size();  // 获取数组的大小
    int minLength = INT_MAX;  // 初始化最小长度为最大整数

    for (int start = 0; start < n; start++) {  // 以每个元素为起点
        int sum = 0;  // 定义当前子数组的和

        for (int end = start; end < n; end++) {  // 从起点开始遍历子数组
            sum += nums[end];  // 向子数组内添加元素

            if (sum >= s) {  // 如果子数组的和满足条件
                minLength = min(minLength, end - start + 1);  // 更新最小长度
                break;  // 退出内层循环,继续下一个起点
            }
        }
    }

    // 如果minLength没有被更新,说明没有满足条件的子数组,返回0;否则返回最小长度
    return minLength == INT_MAX ? 0 : minLength;
}

int main() {
    int s = 7;  // 给定的正整数s
    vector<int> nums = {2, 3, 1, 2, 4, 3};  // 给定的正整数数组

    // 调用函数找到满足条件的最短连续子数组的长度(暴力法)
    int result = minSubArrayLen(s, nums);

    cout << "最小连续子数组的长度为:" << result << endl;  // 输出结果

    return 0;
}

        时间复杂度:O(n^2)
        空间复杂度:O(1)

滑动窗口

#include <iostream>
#include <vector>
#include <climits> // 包含 <climits> 头文件以引入 INT_MAX

using namespace std;

// 定义一个函数,找到满足和≥s的最短连续子数组的长度
int minSubArrayLen(int s, vector<int>& nums) {
    int n = nums.size();  // 获取数组的大小
    int minLength = INT_MAX;  // 初始化最小长度为最大整数
    int left = 0;  // 定义左指针
    int sum = 0;  // 定义当前窗口内元素的和

    for (int right = 0; right < n; right++) {  // 使用右指针遍历数组
        sum += nums[right];  // 向窗口内添加一个元素

        while (sum >= s) {  // 当窗口内元素和大于等于s时
            minLength = min(minLength, right - left + 1);  // 更新最小长度
            sum -= nums[left];  // 缩小窗口,左指针向右移动
            left++;  // 左指针向右移动
        }
    }

    // 如果minLength没有被更新,说明没有满足条件的子数组,返回0;否则返回最小长度
    return minLength == INT_MAX ? 0 : minLength;
}

int main() {
    int s = 7;  // 给定的正整数s
    vector<int> nums = {2, 3, 1, 2, 4, 3};  // 给定的正整数数组

    // 调用函数找到满足条件的最短连续子数组的长度
    int result = minSubArrayLen(s, nums);

    cout << "最小连续子数组的长度为:" << result << endl;  // 输出结果

    return 0;
}

        时间复杂度:O(n)
        空间复杂度:O(1)

打卡

        暴力做法打卡

        滑动窗口打卡

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

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

相关文章

用CHAT分析高校体育智慧教学体系构建与探索研究现状

CHAT回复&#xff1a;现阶段&#xff0c;高校体育智慧教学体系的构建与探索研究还处于初级阶段&#xff0c;但全球数字化转型大潮的推动下&#xff0c;一些较为前沿的研究和实践已经开始出现&#xff1a; 1.教学平台的建设&#xff1a;很多高校已经开始尝试使用在线教育平台进行…

锂离子电池二阶RC等效电路模型参数

目前锂离子电池二阶RC等效电路模型是较多学者进行研究的模型&#xff0c;不同的锂离子电池模型参数有差别&#xff0c;但大致在这个范围内&#xff0c;可参考。 等效电路模型&#xff1a; 部分文献离线参数辨识结果&#xff1a; 另一文献的辨识结果&#xff1a;

e2studio开发三轴加速度计LIS2DW12(3)----检测活动和静止状态

e2studio开发三轴加速度计LIS2DW12.3--检测活动和静止状态 概述视频教学样品申请源码下载新建工程工程模板保存工程路径芯片配置工程模板选择时钟设置UART配置UART属性配置设置e2studio堆栈e2studio的重定向printf设置R_SCI_UART_Open()函数原型回调函数user_uart_callback ()…

【刷题】 leetcode 2 .两数相加

两数相加 两数相加1 思路一 &#xff08;暴毙版&#xff09;2 思路二 &#xff08;本质出发&#xff09; 谢谢阅读Thanks♪(&#xff65;ω&#xff65;)&#xff89;下一篇文章见&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 两数相加 我们来看…

系统架构的演变:从单体到微服务的旅程

文章目录 前言一、单体架构简图 二、垂直架构简图 三、水平架构简图 四、面向服务架构&#xff08;SOA&#xff09;简图 五、微服务架构简图 总结 前言 随着信息技术的快速发展&#xff0c;系统架构也在不断演变。从早期的单体架构到现代的微服务架构&#xff0c;每一次的变革都…

Numpy的学习 第一课 了解以及使用

1.输入模式 1.编辑模式 绿色2.命令模式 蓝色 2.运行 直接输入jupyter notebook 3.文档注释 查看函数帮助文档命令 help(函数) 单问号与多问号 单问号显示文档 多问号显示文档代码 3.shifttab 显示参数 4.运行外部文件 %run 路径,可绝对可相对 这里运行了就相当于方法了,或者…

C++ 之LeetCode刷题记录(十二)

&#x1f604;&#x1f60a;&#x1f606;&#x1f603;&#x1f604;&#x1f60a;&#x1f606;&#x1f603; 开始cpp刷题之旅。 依旧是追求耗时0s的一天。 69. x 的平方根 示例 1&#xff1a; 输入&#xff1a;x 4 输出&#xff1a;2 示例 2&#xff1a; 输入&#x…

软件测试|使用Python轻松裁剪视频

简介 裁剪视频是在视频编辑和处理中常见的任务之一&#xff0c;Python提供了多种库和工具&#xff0c;可以用来裁剪视频。在本文中&#xff0c;我们将详细讨论如何使用Python来裁剪视频&#xff0c;并提供示例代码。 步骤1&#xff1a;环境准备 首先&#xff0c;我们要安装必…

交换机配置及网络测试

实验环境 拓扑图 Ip规划表 部门 主机数量 网络地址 子网掩码 网关 可用ip Vlan 市场部 38 192.168.131.0 255.255.255.0 192.168.131.1 2-254 11 研发部 53 192.168.132.0 255.255.255.0 192.168.132.1 2-254 12 财务部 9 192.168.133.0 255.255.255…

更适合3D项目的UI、事件交互!纯国产数字孪生引擎持续升级中!!!

UI和事件交互是3D可视化项目中最常见的模块&#xff0c;主要用于信息添加、展示&#xff0c;用来确保按照用户需求呈现内容并完成交互。 平时工作在进行UI和交互设计时&#xff0c;经常出现以下问题&#xff1a;UI过于复杂导致3D项目内交互效率低下&#xff0c;或者是结合3D项目…

重磅!鼎捷参与编写的《小灯塔企业数字化转型能力成熟度模型》团体标准发布

近日&#xff0c;由上海市计算机行业协会组织发起&#xff0c;鼎捷软件参与起草的《小灯塔企业数字化转型能力成熟度模型》团体标准正式发布。标准旨在共同推动业内标准的设定和完善&#xff0c;加快企业的数字化转型&#xff0c;助力产业快速发展。 作为业内专业的数字化转型服…

【第65例】IPD体系进阶:PDT跨职能团队

内容简介 这节内容主要来谈谈 IPD 体系中的一个关键跨职能团队(PDT)。 跨部门协作也是 IPD 中的一个核心思想。 这是因为创新和研发是全公司的行为。 接力棒式的产品开发流程是很难保证最终的产品质量。 在 IPD 体系中,无论是需求管理、产品和技术规划、项目任务书开发…

【技术分享】远程透传网关-单网口快速实现西门子S7-300/400 PLC程序远程上下载

准备工作 一台可联网操作的电脑一台单网口的远程透传网关及博达远程透传配置工具网线一条&#xff0c;用于实现网络连接和连接PLC一台西门子S7- 300/400 PLC及其编程软件一张4G卡或WIFI天线实现通讯(使用4G联网则插入4G SIM卡&#xff0c;WIFI联网则将WIFI天线插入USB口&#…

【架构】docker实现3主3从架构配置【案例1/4】

一&#xff0c;集群规划及准备工作 架构实现&#xff1a;Redis3主3从 二&#xff0c;搭建命令 第一步&#xff0c;创建6台服务&#xff1a; docker run -d --name redis-node-1 --net host --privilegedtrue -v /data/redis/share/redis-node-1:/data redis:6.0.8 --clust…

全球移动通信市场,正在经历哪些新变化?

2023年已经结束了。回顾这一年的全球移动通信市场&#xff0c;如果让我用一个词来总结&#xff0c;那就是——“厚积薄发”。 从表面上来看&#xff0c;似乎并没有什么大事情发生。但实际上&#xff0c;平静的湖面之下&#xff0c;却是一片波涛汹涌、风云激荡。 无论是消费互联…

python使用Apache+mod_wsgi部署Flask

python使用Apachemod_wsgi部署Flask 一、安装python环境&#xff08;V3.10.10&#xff09;二、安装mod_wsgi三、安装Apache1、下载2、解压3、配置 四、安装项目依赖五、启动六、基于多端口部署多个flask项目 一、安装python环境&#xff08;V3.10.10&#xff09; 安装时勾选&q…

小白准备蓝桥杯之旅(c/c++b组)

前言&#xff1a;省赛获奖比例高达百分之60,只要比一半的人努力&#xff0c;你就能大概率获奖。 寒假做的3件事 1.稳基础 熟练掌握基础语法部分&#xff0c;c比c多个stl库优势&#xff0c;c语言的同学需要会实现c中stl库部分 2.刷真题 大概比赛前30天&#xff0c;坚持每天做…

中级软件架构师----UML包图知识点汇总

包图知识目录目录 包的属性元素与包的关系包与包的关系 包的属性 每个包必须有一个与其他包相区别的名称&#xff0c;有简单名和路径名之分&#xff0c;简单名是仅含一个简单的名称&#xff1b;路径名是以包所位于的外围包的名字作为前缀的包名。包元素的可见性&#xff0c;号…

阿里云 linux Centos7 安装 Miniconda3 + 创建Python环境

1.下载miniconda &#xff08;1&#xff09;法一&#xff1a;可以去下载清华源的miniconda镜像源&#xff0c;选择自己需要的版本&#xff0c;然后上传到Linux服务器上&#xff0c;linux上使用请选择linux版本&#xff0c;如下&#xff1a; &#xff08;2&#xff09;法二&…

基于SSM的毕业生就业管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue、HTML 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是…