
本文详解 leetcode 第643题“最大平均子数组 i”的滑动窗口解法,指出常见逻辑错误(如混淆窗口长度与元素和),并提供简洁、正确的实现及关键原理说明。
本文详解 leetcode 第643题“最大平均子数组 i”的滑动窗口解法,指出常见逻辑错误(如混淆窗口长度与元素和),并提供简洁、正确的实现及关键原理说明。
在解决“求长度为 k 的连续子数组的最大平均值”问题时,核心在于理解:平均值最大 ⇔ 子数组和最大(因分母 k 固定)。因此,无需实时计算平均值,只需维护长度恒为 k 的滑动窗口,并追踪其最大和,最后除以 k 即得答案。
原代码中存在几个关键逻辑错误:
- ❌
while temp > k:temp是当前窗口元素之和,k是窗口长度,二者量纲不同,不可直接比较; - ❌
curr += 1在for循环中冗余且错误:Python 的for curr in range(len(nums))已自动递增curr,手动加一将导致索引错位; - ❌ 窗口长度未被显式约束为 k:代码试图用
temp > k动态缩窗,但实际需求是窗口必须严格等于 k 个元素,而非满足某个和的阈值; - ❌
ans = temp / (curr - left + 1)中分母动态变化,违背题目要求(子数组长度必须为 k)。
✅ 正确思路是标准的定长滑动窗口(Fixed-size Sliding Window):
- 先计算首个长度为 k 的窗口和(
nums[0:k]); - 从第 k 个元素开始遍历,每次将窗口右移一位:减去左边界元素
nums[i−k],加上新右边界元素nums[i]; - 持续更新最大和;
- 最终返回
maxSum / k。
以下是清晰、健壮的实现:
class Solution:
def findMaxAverage(self, nums: List[int], k: int) -> float:
# 初始化第一个长度为 k 的窗口和
curr_sum = sum(nums[:k])
max_sum = curr_sum
# 滑动窗口:i 为新加入的右端索引(从 k 开始)
for i in range(k, len(nums)):
curr_sum = curr_sum - nums[i - k] + nums[i]
max_sum = max(max_sum, curr_sum)
return max_sum / k
⚠️ 注意事项:
- 时间复杂度为 O(n),空间复杂度为 O(1),远优于暴力 O(n×k) 解法;
- 无需使用浮点数初始化
ans = 0.0—— 整数除法在 Python 3 中自动返回float; - 输入保证
k ≤ len(nums),故无需额外边界校验(LeetCode 题目约束); - 若需扩展为「长度 ≥ k」或「长度 ≤ k」的最大平均子数组,则需改用前缀和 + 二分搜索(如 LeetCode 644),但本题仅需定长滑窗。
掌握这一模式不仅能解决本题,更是理解滑动窗口思想的关键入口:明确窗口不变量(此处为长度恒为 k),避免在循环中混入无关条件判断,让逻辑聚焦于“移入—移出—更新”三步主干。










