给你一个由 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.length
1 <= k <= n <= 105
-104 <= nums[i] <= 104
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximum-average-subarray-i
(1)滑动窗口1
可以使用滑动窗口来解题本题,具体步骤如下:
① 定义变量 res,用于保存题目中的最大平均值,初始值为 Integer.MIN_VALUE
② 构建窗口大小为 k 的滑动窗口,初始的左右端点分别为 nums[0] 和 nums[k - 1],然后求出该窗口元素的平均值,并更新 res;
③ 窗口开始向右滑动,此时用 sum = sum - nums[i - 1] + nums[i + k - 1] 表示新的元素 (nums[i + k - 1]) 被添加进窗口,旧的元素被移出窗口 (nums[i - 1]),这样就避免了重新求窗口内的元素和,然后再更新 res;
④ 遍历结束后,返回 res 即可。
(2)滑动窗口2
该思路参考本题官方题解。
方法1大体上与官方题解类似,但是官方题解在一些地方做了优化,减少了一些不必要的计算,例如可以先求出长度为 k 的连续子数组的最大和,最后再用该和去除以 k 求得长度为 k 的连续子数组的最大平均数,这样一来整个代码中只有一处需要做除法运算。
//思路1————滑动窗口
class Solution {
public double findMaxAverage(int[] nums, int k) {
double res = Integer.MIN_VALUE;
int n = nums.length;
if (n == 1) {
return nums[0];
}
int sum = 0;
for (int i = 0; i <= n - k; i++) {
if (i == 0) {
for (int j = 0; j < k; j++) {
sum += nums[j];
}
res = Math.max(res, (double) sum / k);
} else {
sum = sum - nums[i - 1] + nums[i + k - 1];
res = Math.max(res, (double) sum / k);
}
}
return res;
}
}
//思路2————滑动窗口2
class Solution {
public static double findMaxAverage(int[] nums, int k) {
int n = nums.length;
if (n == 1) {
return nums[0];
}
int sum = 0;
for (int i = 0; i < k; i++) {
sum += nums[i];
}
int maxSum = sum;
maxSum = Math.max(maxSum, sum);
for (int i = 1; i <= n - k; i++) {
sum = sum - nums[i - 1] + nums[i + k - 1];
maxSum = Math.max(maxSum, sum);
}
return (double)maxSum / k;
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_43004044/article/details/125777890
内容来源于网络,如有侵权,请联系作者删除!