当前位置: 首页 > news >正文

Leetcode题解:209长度最小的子数组,掌握滑动窗口从此开始!!!

一、题目内容

题目要求找出给定数组中满足总和大于等于目标值 target 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

二、题目分析

1. 输入和输出

  • 输入

    • 一个正整数数组 nums,表示给定的数组。

    • 一个正整数 target,表示目标值。

  • 输出

    • 一个整数,表示满足总和大于等于 target 的长度最小的连续子数组的长度。如果不存在符合条件的子数组,则返回 0。

2. 算法逻辑

  • 使用滑动窗口算法来解决这个问题。

  • 初始化两个指针 leftright,分别表示窗口的左右边界,初始值均为 0。

  • 初始化一个变量 sum,用于存储当前窗口内的元素和,初始值为 0。

  • 初始化一个变量 min_length,用于存储满足条件的最短子数组的长度,初始值为正无穷大(INT_MAX)。

  • 遍历数组:

    • right 指针所指向的元素值加入 sum

    • 如果 sum 大于等于 target,则尝试通过移动 left 指针来缩小窗口,同时更新 min_length

    • 移动 right 指针,继续扩展窗口。

  • 遍历结束后,如果 min_length 仍为正无穷大,说明没有找到符合条件的子数组,返回 0;否则返回 min_length

三、解题要点

1. 滑动窗口的定义

滑动窗口是一种用于解决数组或字符串问题的有效算法,特别适用于处理涉及连续子数组(串)的问题。在本题中,滑动窗口用于动态调整子数组的范围,以找到满足条件的最短子数组。

2. 窗口的移动

  • 右指针移动:右指针不断向右移动,将新元素加入窗口,累加窗口内的和。

  • 窗口收缩:当窗口内的和大于等于 target 时,尝试通过移动左指针来缩小窗口,同时更新最小长度。

3. 算法复杂度

  • 时间复杂度:O(n),其中 n 是数组的长度。每个元素最多被访问两次(一次由右指针,一次由左指针)。

  • 空间复杂度:O(1),只需要常数级别的额外空间。

四、代码解答

以下是使用滑动窗口算法的 C++ 实现代码:

#include <vector>
#include <algorithm>
#include <climits>class Solution {
public:int minSubArrayLen(int target, std::vector<int>& nums) {int n = nums.size();int left = 0, right = 0;int sum = 0;int min_length = INT_MAX;while (right < n) {sum += nums[right]; // 将右指针的值加入窗口while (sum >= target) { // 如果窗口内的和大于等于目标值min_length = std::min(min_length, right - left + 1); // 更新最小长度sum -= nums[left]; // 移动左指针,缩小窗口left++;}right++;}return (min_length == INT_MAX) ? 0 : min_length; // 如果没有找到满足条件的子数组,返回0}
};

以下是c语言实现代码:

int minSubArrayLen(int target, int* nums, int numsSize) {// 初始化变量int len = 0;            // 用于记录当前满足条件的子数组长度int sum = 0;            // 当前窗口内的元素和int left = 0;           // 左指针,表示窗口的左边界int min_len = numsSize + 1; // 用于记录最小长度,初始值设为数组长度加1(一个不可能达到的值)// 遍历数组,右指针从0到numsSize-1for (int i = 0; i < numsSize; i++) {// 将右指针所指向的元素值加入窗口和sum += nums[i];// 当窗口内的和大于等于目标值时,尝试收缩窗口while (sum >= target) {// 计算当前窗口的长度len = i - left + 1;// 如果当前窗口长度小于已记录的最小长度,则更新最小长度if (len < min_len) {min_len = len;}// 移动左指针,缩小窗口,并从窗口和中减去左指针所指向的元素值sum -= nums[left];left++;}}// 如果min_len仍大于numsSize,说明没有找到满足条件的子数组,返回0// 否则返回找到的最小长度return (min_len > numsSize) ? 0 : min_len;
}

五、详细注释

1. 滑动窗口算法

  • 窗口扩展:右指针向右移动,将新元素加入窗口,累加窗口内的和。

  • 窗口收缩:当窗口内的和大于等于 target 时,尝试通过移动左指针来缩小窗口,同时更新最小长度。

2. 终止条件

  • 当右指针遍历完整个数组时,结束循环。

3. 返回值

  • 如果没有找到满足条件的子数组,返回 0。

  • 否则返回找到的最短子数组的长度。

六、代码执行过程示例

假设我们有一个数组 nums = [2, 3, 1, 2, 4, 3] 和目标值 target = 7

代码执行过程

  1. 初始状态

    • left = 0, right = 0, sum = 0, min_length = INT_MAX

  2. 右指针移动

    • right = 0, sum = 2

    • right = 1, sum = 5

    • right = 2, sum = 6

    • right = 3, sum = 8(满足条件)

  3. 左指针移动

    • left = 0, sum = 8, min_length = 4

    • left = 1, sum = 6, min_length = 4

    • left = 2, sum = 5, min_length = 4

    • left = 3, sum = 4, min_length = 4

  4. 右指针继续移动

    • right = 4, sum = 8(满足条件)

    • left = 3, sum = 8, min_length = 3

    • left = 4, sum = 4, min_length = 3

  5. 右指针继续移动

    • right = 5, sum = 7(满足条件)

    • left = 4, sum = 7, min_length = 2

    • left = 5, sum = 3, min_length = 2

  6. 结束

    • right = 6,结束循环

    • 返回 min_length = 2

最终结果

最终返回的最小长度为 2,对应的子数组为 [4, 3]

http://www.xdnf.cn/news/1167733.html

相关文章:

  • Android13重置锁屏(1)
  • 碰一碰发视频源码搭建:支持OEM
  • 现在希望用git将本地文件crawler目录下的文件更新到远程仓库指定crawler目录下,命名相同的文件本地文件将其覆盖
  • 【Tomcat】Tomcat线程池深度调优手册(终极版)
  • 用USBi仿真器的SPI模式和IIC模式来调试DSP应该怎么做?
  • Vue项目中的AJAX请求与跨域问题解析
  • Linux CentOS 虚拟机升级内核至4.x以上版本
  • 异构融合 4A:重构高性能计算与复杂场景分析的安全与效率边界
  • Go 的第一类对象与闭包
  • Vercel AI SDK 3.0 学习入门指南
  • 厚铜板载流革命与精密压合工艺——高可靠性PCB批量制造的新锚点
  • 容器化部署 Tomcat + MySQL 实战指南:从入门到进阶
  • 分布式高可用ELK平台搭建及使用保姆级教程指南
  • 智能制造——解读52页汽车设计制造一体化整车产品生命周期PLM解决方案【附全文阅读】
  • linux用户态各定时器抖动测试
  • 操作符练习
  • 【Linux内核模块】模块声明与描述
  • nginx使用手册
  • 在easyui中如何自定义表格里面的内容
  • MCU中的总线桥是什么?
  • 分布在内侧内嗅皮层(MEC)的边界细胞对NLP中的深层语义分析的积极影响和启示
  • 深入浅出理解 TCP 与 UDP:网络传输协议的核心差异与应用
  • JMeter groovy 编译成.jar 文件
  • oracle里面concat函数用法,oracle wm_concat函数用法-
  • python学习-读取csv大文件
  • Apache Ignite实现无死锁特性
  • PHP与Web页面交互:从基础表单到AJAX实战
  • k8s:利用helm离线部署consul v1.21.2
  • 【菜狗学聚类】时间序列聚类主要方法—20250722
  • web3.0怎么入局