当前位置: 首页 > 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.jsqmd.com/news/1079146/

相关文章:

  • 电机性能测试系统:集性能评估与耐久验证于一体
  • Kioxia签署第20届亚运会和第5届亚残运会合作协议
  • 专知智库 × 余行专利 × 自指专利池让“自指”为新院校插上科研与产业化的翅膀
  • 为什么专业图像查看器是游戏开发者的必备工具?探索Tacent View的完整解决方案
  • 2026年低成本创作指南,高性价比 AI 视频生成工具实测盘点
  • Security Onion:一体化开源安全监控平台部署与实战指南
  • 在Windows上进行Docker 部署速成指南(SpringBoot + Vue + MySQL + Redis)
  • AI新闻发布:出海品牌构建长期传播资产的内容路径
  • 2026 年高效的 ai 做网站系统有哪些,新手建站工具整理
  • “中标公示”与“合同公告”同日发布,真的违法吗?
  • 从信息收集到权限提升:一次完整的Linux服务器渗透测试实战复盘
  • Rademacher公式在pod2(n)精确计算中的应用与实现
  • 057、Zephyr RTOS内核基础:工作队列与延迟工作
  • 2026 长期命理趋势怎么分析?玄易AI工具测评
  • 跨境电商进入中东:客服做不好,你连第一单都接不到
  • LLaMA Factory:100+大模型统一微调平台
  • 我想认真做一件小事:让孩子和家长更好地互动
  • 布局谷歌GEO前,值得了解的几点思路
  • 浏览器页面渲染流程
  • 文档下载终极解决方案:如何绕过30+平台限制获取任意可见内容
  • Obsidian Excel转Markdown表格插件:3分钟解决表格粘贴难题
  • 人工智能参与工业化精密加工的物理效率
  • 自我介绍与未来展望
  • 区域PACS源码,java云PACS源码,影像归档系统源码,自主产品,适合二开
  • 2026 年广州网站开发公司前十,综合实力榜单出炉
  • HarmonyOS技术精讲-UI开发调试调优:内存泄漏与组件复用实战
  • 33-静态源码入库与异步落库:为什么静态结构要先缓存再落仓
  • Webug4.0文件上传漏洞实战:从JS绕过到.htaccess攻击全解析
  • 国产信创环境Codex适配实战指南
  • VS Code + Continue 接入 Claude API 完整配置教程(含排障)