固定窗口大小k时滑动窗口求最大和为o(n):先算前k个元素和,再每次减左加右更新,避免暴力o(nk);若窗口大小不固定则应用kadane算法。
java 中用数组实现滑动窗口求连续子数组最大和,本质是避免重复计算——不是用滑动窗口解决“最大子数组和”(那是 kadane 算法的主场),而是当问题明确限定**窗口大小固定(如长度为 k 的连续子数组)且需频繁求和时**,滑动窗口才能真正发挥 o(n) 优势,绕过暴力 o(nk) 的性能瓶颈。
明确适用场景:固定长度窗口的最大/最小和
滑动窗口在此类问题中高效,前提是窗口长度 k 固定。例如:“给定整数数组 nums 和整数 k,返回所有长度为 k 的连续子数组中的最大和”。暴力解法对每个起点 i 都调用 Arrays.stream(nums, i, i+k).sum(),时间复杂度 O(nk);而滑动窗口只需一次遍历。
- 初始化窗口:计算前 k 个元素和 sum
- 滑动过程:每右移一位,sum = sum - nums[i] + nums[i+k](减左边界,加右边界)
- 全程维护 maxSum,无需重新累加
数组实现要点:避免越界与索引偏移
使用原始数组而非 ArrayList,减少封装开销;注意下标从 0 开始,窗口右边界为 i + k - 1,滑动时 i 的范围是 0 到 nums.length - k(含)。
示例代码关键片段:
int sum = 0; for (int i = 0; i
若 k > nums.length,直接返回 0 或抛 IllegalArgumentException,不进入循环。
对比 Kadane 算法:别混淆问题类型
如果题目是“求任意长度连续子数组的最大和”(即经典最大子数组和),滑动窗口不适用——因为窗口大小不固定。此时应使用 Kadane 算法,时间复杂度 O(n),空间 O(1):
- 维护 currSum = Math.max(nums[i], currSum + nums[i])
- 同步更新 globalMax
- 它本质是动态规划,不是滑动窗口
强行套用固定窗口去解该题,会漏掉长度 ≠ k 的更优解,逻辑错误。
进阶优化:处理大数组与溢出
当 nums 元素绝对值大、k 较大时,sum 可能溢出 int。应根据数据范围选用 long 类型存储和比较:
- 声明
long sum = 0, maxSum = Long.MIN_VALUE - 返回值按题意决定是否转为 int(需确认无溢出风险)
- 避免在循环内反复装箱/拆箱(如用 Long.valueOf())
对于超大规模数组(如上千万元素),可考虑分段预处理前缀和加速,但通常纯滑动窗口已足够高效。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











