滑动窗口算法中tempSum = tempSum - arr[i - num] + arr[i]语句疑问
滑动窗口中
arr[i - num]的逻辑与num的作用解释 先看你的代码示例:
function maxSubarraySum(arr, num) { let maxSum = 0 let tempSum = 0 if (arr.length < num) return null for (let i = 0; i < num; i++) { maxSum += arr[i] } tempSum = maxSum for (let i=num; i < arr.length; i++) { tempSum = tempSum - arr[i - num] + arr[i] maxSum = Math.max(maxSum, tempSum) } return maxSum } console.log(maxSubarraySum([2,1,4,7,4,5,2,6,4,3], 3))
你理解的滑动窗口核心逻辑是对的——不用重新遍历整个窗口,只需要移出左端元素、加入右端新元素。但你疑惑的arr[i - num]和num的作用,本质是因为num是窗口的固定长度,它决定了每次滑动时要移除的元素位置,而不是只用来控制初始迭代的长度。
咱们结合例子(num=3,数组[2,1,4,7,4,5,2,6,4,3])一步步拆解:
1. num的核心定义:固定窗口长度
num不是“仅用于控制迭代长度”,它是滑动窗口的大小——整个算法中,我们始终维护一个长度为num的连续子数组,所有操作都是围绕这个固定长度展开的。
2. 为什么用arr[i - num]而不是直接减arr[0]?
看第二个循环的i变量:
- 循环从
i=num开始(例子里就是i=3,对应数组元素7),此时我们要把窗口从[2,1,4](索引0-2)滑到[1,4,7](索引1-3)。需要移除的是上一个窗口的左端元素2,它的索引是0,而i - num = 3 - 3 = 0,正好命中这个索引。 - 下一次循环
i=4(对应元素4),窗口要滑到[4,7,4](索引2-4),需要移除的是上一个窗口的左端元素1(索引1),i - num =4-3=1,精准定位。 - 再下一次
i=5(元素5),窗口滑到[7,4,5](索引3-5),要移除的是4(索引2),i - num=5-3=2,完全正确。
如果直接减arr[0],那每次滑动都会移除数组的第一个元素,得到的根本不是连续的滑动窗口——比如第二次循环后,tempSum会变成7-2+4=9,对应的是[1,4,7,4],长度变成了4,完全违背了“固定长度为3的子数组”的要求,结果自然错误。
3. num在整个算法中的作用
- 初始化窗口:第一个循环用
num控制遍历前num个元素,计算初始的窗口和。 - 滑动时定位移除元素:通过
i - num,用当前新加入元素的索引i,反向推导出上一个窗口左端元素的索引,确保每次滑动后窗口长度始终保持num。
这样整个滑动过程才能高效地维护固定长度的窗口,时间复杂度从O(n*num)降到O(n),这也是滑动窗口算法的核心优势。
内容的提问来源于stack exchange,提问作者Akhror Khamidov
相关产品推荐
相关产品推荐

