leetcode-643 子数组最大平均数 I
题目
给你一个由 n 个元素组成的整数数组 nums 和一个整数 k 。
请你找出平均数最大且长度为 k 的连续子数组,并输出该最大平均数。
任何误差小于 \(10^{-5}\) 的答案都将被视为正确答案。
示例 1:
输入:nums = [1,12,-5,-6,50,3], k = 4
输出:12.75
解释:最大平均数 (12-5-6+50)/4 = 51/4 = 12.75
示例 2:
输入:nums = [5], k = 1
输出:5.00000
提示:
n == nums.length1 <= k <= n <= 105-10^4<= nums[i] <= 104
思路
- 题目要求一个固定长度的连续子数组,符合滑动窗口算法的问题特征;
- 题目求子数组的最大平均数,因为数组长度的固定的,所以也相当于求子数组最大和
- 首先进行边界处理,如果数组长度小于要求子数组长度,则直接返回 0,表示无满足条件的解;
- 先求出第一个窗口和(位置 0 到 k-1),后续就在第一个窗口的基础上进行更新即可,并将第一个窗口和作为最大窗口和初始值;
- 开始滑动窗口,由于已经计算过第一个窗口和,所以第二个窗口的右边界就从索引 k 开始,第二个窗口和就在第一个窗口和基础上加上右边界值(nums[i])同时减去左边界值(nums[i-k]),后续窗口和计算以依此类推;
- 每次移动计算窗口和后,和最大窗口和进行比较,如果大于保存的最大窗口和,则更新最大窗口和;
- 当窗口右边界超出给定数组长度时,窗口滑动结束,计算最大窗口和除以固定长度 k 获得最大平均数并返回;
- 时间复杂度:\(O(n)\),其中 \(n\) 为数组长度,因为只需要遍历数组一次,每个元素最多被访问两次。
- 空间复杂度:\(O(1)\)。只需要使用常数个变量存储窗口和、最大和等信息。
go 实现示例
func findMaxAverage(nums []int, k int) float64 {
// 获取数组长度,并进行边界处理
n := len(nums)
if n < k {
return 0
}
// 计算第一个窗口的和
sum := 0.0
for i:=0;i<=k-1;i++ {
sum += float64(nums[i])
}
// 初始化最大窗口和
maxSum := sum
// 开始滑动窗口,注意右边界从k开始
for i:=k;i<len(nums);i++ {
sum += float64(nums[i]) - float64(nums[i-k])
// 如果当前窗口和大于最大窗口和,则更新最大窗口和
if sum > maxSum {
maxSum = sum
}
}
// 返回最大窗口和除以固定长度k,即为最大平均数
return maxSum/float64(k)
}

浙公网安备 33010602011771号