news 2026/6/26 4:21:00

滑动窗口解法:最短子数组长度代码解释与优化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
滑动窗口解法:最短子数组长度代码解释与优化

目录

一、代码逐行解释(滑动窗口解法:最短子数组长度)

原代码完整拆解

原代码存在的 BUG & 缺陷

二、标准优化版滑动窗口(双指针)

优化思路

三、优化点对比说明

四、逻辑流程演示(举例)

五、补充:二分前缀和解法(进阶 O (nlogn))


一、代码逐行解释(滑动窗口解法:最短子数组长度)

题目:LeetCode 209 长度最小的子数组 给定正整数数组nums和目标值target,找出总和 ≥ target 的连续子数组的最小长度,不存在返回 0。

原代码完整拆解

class Solution { public int minSubArrayLen(int target, int[] nums) { // 记录最小窗口长度,初始为最大值(代表没找到合法窗口) int min = Integer.MAX_VALUE; // 当前窗口 [left, right] 的元素和 int sum = 0; int left = 0; // 窗口左边界 int right = 0;// 窗口右边界 int length = nums.length; sum = nums[0]; // 先把第一个元素加入窗口 // 第一个元素直接大于target,最短长度就是1,直接返回 if(sum>target){ return 1; } // 外层循环:右指针最多走到倒数第二个元素 while (right<length-1){ // 内层1:窗口和不足target,不断右移右指针扩大窗口 while (sum<target&&right<length-1){ right++; sum += nums[right]; } // 内层2:窗口和满足条件,不断右移左指针缩小窗口,更新最小长度 while (sum>=target){ if(min>right - left+1){ min = right - left +1; } sum -= nums[left]; left++; } } // 如果min没更新过,说明无合法子数组返回0,否则返回最小长度 return min == Integer.MAX_VALUE?0:min; } }

原代码存在的 BUG & 缺陷

  1. 边界初始化缺陷
    • 数组为空、数组长度 = 1 时会报错nums[0]数组越界;
    • 提前写死sum = nums[0],破坏滑动窗口统一初始化逻辑。
  2. 外层循环限制错误right < length -1导致右指针无法走到数组最后一位,最后一个元素永远无法纳入窗口,测试用例极易出错。
  3. 冗余特判if(sum>target) return 1滑动窗口内部逻辑完全可以覆盖该场景,属于多余代码。
  4. 逻辑耦合、可读性差三层嵌套循环结构臃肿,标准滑动窗口只需要一层外层循环控制右指针。
  5. 变量命名尚可,但流程不标准

二、标准优化版滑动窗口(双指针)

优化思路

  1. 统一初始化:sum=0left=0,右指针从头遍历到尾,消除数组越界;
  2. 去掉多余特判,一套逻辑覆盖所有场景;
  3. 单层外层循环控制右指针,满足和≥target 时收缩左边界;
  4. 增加数组判空,鲁棒性更强;
  5. 简化长度更新代码;
  6. 时间复杂度 O (n),每个元素仅被左右指针各访问一次。
class Solution { public int minSubArrayLen(int target, int[] nums) { // 边界:空数组直接返回0 if (nums == null || nums.length == 0) { return 0; } int n = nums.length; int minLen = Integer.MAX_VALUE; int sum = 0; int left = 0; // 右指针从头到尾遍历,一层循环即可 for (int right = 0; right < n; right++) { sum += nums[right]; // 扩大右边界 // 当窗口和满足条件,持续收缩左边界,更新最小长度 while (sum >= target) { minLen = Math.min(minLen, right - left + 1); sum -= nums[left]; left++; } } // 未找到合法子数组返回0 return minLen == Integer.MAX_VALUE ? 0 : minLen; } }

三、优化点对比说明

问题优化方案
访问 nums [0] 越界sum 初始 0,循环内逐个加 nums [right],兼容空 / 长度 1 数组
right 走不到末尾for 循环 right < n,完整遍历全部元素
多余 if 特判单个元素while 收缩窗口自动处理单元素满足 target 场景
三层循环嵌套臃肿外层单层 for,内层仅收缩窗口的 while,逻辑清晰
手动比较更新 min使用Math.min简化代码
无空数组防护开头增加 nums 判空,线上不会 NPE / 数组越界

四、逻辑流程演示(举例)

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

  1. right 不断右移累加 sum,直到 sum≥7
    • right=3 sum=8,进入收缩循环:窗口 [0,3] 长度 4,min=4;sum-=2=6,left=1 退出收缩
  2. right=4 sum=10,收缩:
    • [1,4] 长度 4 → min 不变;sum-3=7 left=2
    • [2,4] 长度 3 → min=3;sum-1=6 left=3 退出
  3. right=5 sum=9,收缩:
    • [3,5] 长度 3 → min 不变;sum-2=7 left=4
    • [4,5] 长度 2 → min=2;sum-4=3 left=5 退出 最终返回 2,正确答案。

五、补充:二分前缀和解法(进阶 O (nlogn))

如果题目允许,还可以用前缀和 + 二分查找,适合数据量极大场景:

class Solution { public int minSubArrayLen(int target, int[] nums) { int n = nums.length; int[] preSum = new int[n + 1]; for (int i = 0; i < n; i++) { preSum[i + 1] = preSum[i] + nums[i]; } int min = Integer.MAX_VALUE; for (int i = 1; i <= n; i++) { int aim = preSum[i] - target; // 二分找最大j满足preSum[j] <= aim int l = 0, r = i; while (l < r) { int mid = l + r >> 1; if (preSum[mid] <= aim) l = mid + 1; else r = mid; } if (l > 0) { min = Math.min(min, i - l + 1); } } return min == Integer.MAX_VALUE ? 0 : min; } }

日常刷题优先滑动窗口 O (n),效率更高、代码更简洁。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/26 4:15:14

32-Git 差异行号计算机制:平台如何知道“哪些行真的变了”

适合对象:关注增量分析、差异行提取、提交比较、代码变更精度的后端工程师和测试平台工程师。 先说结论 Git 差异行号计算机制不是一个孤立功能,而是精准测试平台里帮助团队做判断的一环。 它重点解决的是:平台如何知道“哪些行真的变了”。 用大白话讲,版本能力的重点不…

作者头像 李华
网站建设 2026/6/26 4:15:16

承影Ventus:基于事件驱动的模块化开发者效率平台设计与实践

1. 项目概述&#xff1a;从“承影”到“Ventus”的命名玄机与项目定位最近在和一些做独立开发的朋友聊天时&#xff0c;发现一个挺有意思的现象&#xff1a;大家给项目起名字&#xff0c;越来越讲究了。以前可能就是“XX管理系统”、“XX工具箱”&#xff0c;现在则更倾向于一个…

作者头像 李华
网站建设 2026/6/26 4:08:34

第六届先进制造技术与电子信息国际学术会议(AMTEI 2026)

第六届先进制造技术与电子信息国际学术会议&#xff08;AMTEI 2026&#xff09; 2026 6th International Conference on Advanced Manufacturing Technology and Electronic Information 主办单位&#xff1a;天津理工大学 截稿日期&#xff1a;2026年7月1日 审核录用&#xff…

作者头像 李华
网站建设 2026/6/26 4:03:55

NIKON 4S065-975-2输入输出模块

NIKON 4S065-975-2 输入输出模块是一款用于半导体光刻设备的信号交互组件&#xff0c;以下是其主要产品特点。中间完整产品型号为 NIKON 4S065-975-2。属于输入输出模块类别。由尼康&#xff08;NIKON&#xff09;公司生产制造。主要应用于半导体光刻设备。用于实现设备与控制系…

作者头像 李华
网站建设 2026/6/26 4:01:26

Selenium自动化测试:从元素定位到健壮交互的完整指南

1. 项目概述&#xff1a;从“点鼠标”到“写脚本”的思维跃迁如果你是一名测试工程师&#xff0c;或者是一名对提升工作效率感兴趣的开发者&#xff0c;那么“Selenium自动化测试”这个词对你来说一定不陌生。但很多时候&#xff0c;我们只是停留在“听说过”或者“跑过几个Dem…

作者头像 李华
网站建设 2026/6/26 4:00:44

亲测!浙江高定木作品牌实践分享

开篇&#xff1a;定下基调在高定木作市场日益繁荣的今天&#xff0c;消费者对于高品质、个性化的木作产品需求不断增加。为了帮助广大对高定木作感兴趣的人群挑选到合适的产品&#xff0c;我们开展了本次专业测评。本次参与测评的产品为梦天木作。在此声明&#xff0c;本次测评…

作者头像 李华