news 2026/9/12 0:56:48

LeetCode-Go 题解:643. Maximum Average Subarray I(固定长度滑动窗口求最大平均值)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode-Go 题解:643. Maximum Average Subarray I(固定长度滑动窗口求最大平均值)

LeetCode-Go 题解:643. Maximum Average Subarray I(固定长度滑动窗口求最大平均值)

【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go

导读

本文讲解 LeetCode 第 643 题「Maximum Average Subarray I」在 LeetCode-Go 仓库中的 Go 实现。该题是**固定长度滑动窗口(Fixed-Size Sliding Window)**的入门级经典题目:在给定数组中寻找长度为 k 的连续子数组,使其平均值最大。读完本文你将掌握固定窗口的「先初始化、后滑动」双循环套路,理解为何用整数累加替代浮点累加,并能直接运行仓库内已配套的测试用例验证结果。

关联文档:leetcode/0643.Maximum-Average-Subarray-I/README.md

题目描述

Given an array consisting ofnintegers, find the contiguous subarray of given lengthkthat has the maximum average value. And you need to output the maximum average value.

示例 1:

Input: [1,12,-5,-6,50,3], k = 4 Output: 12.75 Explanation: Maximum average is (12-5-6+50)/4 = 51/4 = 12.75

注意事项:

  1. 1 <= k <= n <= 30,000
  2. 数组中每个元素的取值范围为[-10,000, 10,000]

题目大意

给定n个整数,找出平均数最大且长度为k的连续子数组,并输出该最大平均数。

数据范围与数值溢出分析

在动手编码前,先分析一下数据边界,这直接决定了实现细节:

  • 数组长度最大为n = 30,000
  • 每个元素绝对值最大为10,000
  • 因此窗口长度为k时的最大窗口和绝对值不超过30,000 × 10,000 = 3 × 10⁸

该数量级完全可以安全存入 Go 的int类型(64 位平台为 int64,即便 32 位平台的 int32 上限约 2.1 × 10⁹ 也足以容纳),这就是实现中选择int累加窗口和的数值依据。若换成浮点数float64反复累加再求均值,反而会在连续运算中引入舍入误差,且效率更低。

解题思路:固定长度滑动窗口

原文档给出的思路非常精炼:「简单题。循环一次,扫描数组过程中累加窗口大小为 k 的元素值。不断更新这个最大值。循环结束求出平均值即可。」

拆解开来,这是固定长度滑动窗口的标准三步法:

  1. 初始化窗口:先累加数组前k个元素,得到第一个长度为k的窗口和,记为当前最大和;
  2. 滑动窗口:从下标i = k开始遍历到数组末尾,每向右移动一格,窗口移除最左边的元素nums[i-k]、加入新元素nums[i],得到下一个窗口和:
    sum = sum - nums[i-k] + nums[i]

    这一步的时间复杂度为 O(1),相比每次重新计算k个元素之和(O(k))大大节省了开销;

  3. 更新最大值:每次滑动后,用maxSum = max(maxSum, sum)维护历史最大窗口和。

遍历结束后,maxSum是最大窗口和,由于所有窗口长度都是k,平均值最大等价于窗口和最大,因此最终结果直接除以k即可,无需在滑动过程中频繁做除法。

整个过程只扫描数组一次,时间复杂度 O(n),空间复杂度 O(1)

代码实现(含注释)

仓库中 643. Maximum Average Subarray I.go 的完整实现如下:

package leetcode func findMaxAverage(nums []int, k int) float64 { sum := 0 // 1. 初始化窗口:累加前 k 个元素 for _, v := range nums[:k] { sum += v } maxSum := sum // 2. 滑动窗口:每步 O(1) 完成窗口和的更新 for i := k; i < len(nums); i++ { sum = sum - nums[i-k] + nums[i] maxSum = max(maxSum, sum) } // 3. 最大平均值 = 最大窗口和 / k return float64(maxSum) / float64(k) } func max(a, b int) int { if a > b { return a } return b }

实现要点解读:

  • nums[:k]切片完成窗口初始化,代码简洁且不产生数据拷贝(Go 切片为视图);
  • 滑动时nums[i-k]是被移出窗口的左端元素,nums[i]是新进入窗口的右端元素,两者一减一加即可得到新窗口和;
  • 最终使用float64(maxSum) / float64(k)将整数和转换为浮点平均值。由于最大窗口和不超过 3 × 10⁸(见上文分析),转换过程精度无损;
  • 仓库没有依赖内置的max(Go 1.21 之前标准库无此函数),而是自带了一个局部max辅助函数,保证代码在较低 Go 版本下也可直接编译运行。

测试用例与验证

仓库为本题配套了测试文件 643. Maximum Average Subarray I_test.go,采用「参数-答案」结构组织用例:

type para643 struct { nums []int k int } type ans643 struct { one float64 }

核心测试用例与题目示例一一对应:

qs := []question643{ { para643{[]int{1, 12, -5, -6, 50, 3}, 4}, ans643{12.75}, }, }

即输入[1,12,-5,-6,50,3]k = 4,期望输出12.75,对应窗口(12-5-6+50)/4 = 51/4 = 12.75。该用例同时覆盖了「窗口内包含负数」的场景,验证了算法在混合正负数数组下的正确性。

在仓库根目录执行以下命令即可运行测试:

go test -v -run Test_Problem643 ./leetcode/0643.Maximum-Average-Subarray-I/

为什么归类于滑动窗口与数组专题

在 LeetCode-Go 仓库的专题索引中,本题同时出现在两处:

  • 滑动窗口专题:位于滑动窗口经典题列表内;
  • 数组专题:作为数组类基础题收录。

这反映了题目的双重属性:它是最朴素的固定窗口滑动模型(左右边界同步移动、窗口长度恒定),是理解后续复杂滑动窗口问题(如 0239. Sliding Window Maximum 的单调队列、0480. Sliding Window Median 的堆结构)的起点;同时它也是数组连续子区间求值的基础训练。仓库中同类「固定窗口长度求极值」的姊妹题还包括 1984. Minimum Difference Between Highest and Lowest of K Scores、1052. Grumpy Bookstore Owner 等,均可对比学习。

复杂度与进阶思考

指标说明
时间复杂度O(n)数组仅被完整扫描一次,每步窗口更新为 O(1)
空间复杂度O(1)仅使用summaxSum两个常数级变量,无额外数据结构

两种可选思路的对比:

  • 暴力法:枚举每个长度为k的子数组并重新求和,时间复杂度 O(n·k),在最坏情况(n = 30,000,k ≈ 15,000)下将产生约 4.5 亿次加法运算,明显劣于滑动窗口;
  • 前缀和(Prefix Sum):先构造前缀和数组,再用prefix[i+k] - prefix[i]求窗口和,时间复杂度同为 O(n),但需要 O(n) 的额外空间。本题对空间有更优要求,故滑动窗口方案更佳。

延伸思考:若要求「长度至少为 k」的最大平均子数组,问题升级为 LeetCode 644 题(Maximum Average Subarray II),需要引入二分答案 + 前缀和技巧,这正是从本题出发可以继续深挖的方向。

小结

  • 核心结论:平均值最大等价于窗口和最大,因为所有候选子数组长度固定为k
  • 核心套路:先累加前k个元素初始化窗口,再通过sum = sum - nums[i-k] + nums[i]以 O(1) 代价滑动窗口并维护最大值;
  • 核心实践:用整数累加避免浮点误差,仅在最后一步除以k转换为浮点结果。

通过阅读 题目题解文档、实现源码 与 测试用例,你可以完整复现并验证这一经典固定滑动窗口解法。

【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 0:56:06

AI写作工具横向评测:性价比与创意生成实战分析

1. 项目背景与测试动机最近半年AI工具呈现爆发式增长&#xff0c;各种号称能"降本增效"的产品层出不穷。作为内容创作者&#xff0c;我每天要处理大量文字工作&#xff0c;从初稿撰写到排版优化&#xff0c;时间成本居高不下。上个月团队预算缩减后&#xff0c;我开始…

作者头像 李华
网站建设 2026/9/12 0:51:42

目标级联分析法ATC在MATLAB中的收敛性问题与实现技巧

简介&#xff1a;面向需要求解复杂系统分层优化问题的科研人员与工程师&#xff0c;这套ATC求解资源以目标级联分析法&#xff08;Analytical Target Cascading&#xff09;为核心&#xff0c;提供基于MATLAB的完整计算算例。该算法将设计目标从系统级向子系统、部件逐层分解&a…

作者头像 李华
网站建设 2026/9/12 0:49:01

040、 对话记忆管理:滑动窗口与摘要记忆

040、 对话记忆管理&#xff1a;滑动窗口与摘要记忆 上个月排查一个线上客服 bot&#xff0c;现象很怪&#xff1a;用户聊到第 12 轮&#xff0c;机器人开始把用户早先报过的订单号当成新的&#xff0c;还一本正经地回复“请核对您的订单号”。翻日志发现&#xff0c;prompt 拼…

作者头像 李华
网站建设 2026/9/12 0:48:44

STM32F1轻量级MAVLINK+GPS航点规划实战

简介&#xff1a;本资源是一套面向嵌入式开发者与无人机飞控学习者的MAVLINK与GPS联合解析及航点规划实战例程&#xff0c;基于STM32F1系列MCU实现&#xff0c;聚焦无人机自主导航中的协议解析、定位数据处理与路径规划三大核心环节。资源共240个文件&#xff0c;以166个.h头文…

作者头像 李华
网站建设 2026/9/12 0:47:30

CPO封装玻璃基板选型:从CTE到TGV的核心参数与工程实践

1. 为什么是玻璃基板&#xff1a;CPO 引发的封装材料变局CPO&#xff08;Co-Packaged Optics&#xff0c;共封装光学&#xff09;这几年在数据中心、AI 算力集群里被反复提起&#xff0c;核心逻辑其实很朴素&#xff1a;传统可插拔光模块离交换芯片越来越远&#xff0c;信号经过…

作者头像 李华