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

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

目录

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

原代码完整拆解

原代码存在的 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),效率更高、代码更简洁。

http://www.gsyq.cn/news/1591079.html

相关文章:

  • 从信息收集到权限提升:一次完整的Linux服务器渗透测试实战复盘
  • 我想认真做一件小事:让孩子和家长更好地互动
  • Rademacher公式在pod2(n)精确计算中的应用与实现
  • LLaMA Factory:100+大模型统一微调平台
  • 跨境电商进入中东:客服做不好,你连第一单都接不到
  • 文档下载终极解决方案:如何绕过30+平台限制获取任意可见内容
  • 区域PACS源码,java云PACS源码,影像归档系统源码,自主产品,适合二开
  • 人工智能参与工业化精密加工的物理效率
  • Webug4.0文件上传漏洞实战:从JS绕过到.htaccess攻击全解析
  • JMeter代理服务器配置与脚本录制实战指南
  • 玄通数据,专业用户行为数据分析 SaaS 系统正式入驻企业应用市场
  • 线弹性有限元计算机床自重,并添加切削力负载
  • 从势函数到声子谱:材料计算中的晶格动力学原理与实操指南
  • 逆向工程基础:如何读懂没有源代码的二进制程序
  • 学术打假越来越像流量生意,MedPeer用技术做了一件不一样的事
  • 纤维素纳米纤维接枝聚丙烯酸(CNF-g-PAA)pH响应水凝胶的性能
  • 如何通过RDP Wrapper Library解锁Windows多用户远程桌面功能?
  • 【每日复盘与反思】2026.6.25
  • 跨越语言的二进制光纤(下篇):gRPC 微服务重构与 HTTP/2 多路复用深度拆解
  • Sunshine游戏串流完全指南:打造个人专属云游戏服务器终极教程
  • DMX 报 Agent RPC error (-1): com.kingbase8.utiL.KSQLException: ERROR: relation “sys _database“ does n
  • 锌离子Zn2+响应水凝胶的结构与响应机制
  • 2026软考系规备考:金钟老师是谁?为什么他适合带零基础?
  • 用心做事,方知生活真味
  • 把卖点翻译成购买理由:食品品牌增长链路的结构化方法
  • 如何写一个正确的二分查找?
  • CryptoHack Writeup——Modular Exponentiation:理解RSA中的模幂运算
  • N_m3u8DL-RE:跨平台流媒体下载工具,支持点播和直播
  • 5~60V 恒流驱动HI7002替代惠海 H5116 聚能芯半导体智芯电子一级代理
  • 分类变量编码实战:从数据类型诊断到生产级Pipeline