一、题目描述
给你一个由 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
二、题目解析
1、暴力,双重for循环
class Solution {
public double findMaxAverage(int[] nums, int k) {
if(nums == null || nums.length < k){
return 0;
}
double sum = 0,max = Integer.MIN_VALUE;
int count = 0;
for(int i = 0;i <= nums.length - k;i++){
sum = nums[i];
count = 1;
for(int temp = i + 1;count < k && temp < nums.length;count++,temp++){
sum += nums[temp];
}
max = sum > max ? sum : max;
}
return max / k;
}
}
时间复杂度O((n-k+1)*k),空间复杂度O(1)
运行超时

2、滑动窗口
思考在1基础上,内层for循环可以优化,第一次拿到前4个元素,形成初始窗口,后面向右滑动即可,每次右入1个元素,左出1个元素;在滑动的过程中不断更新最大值。
class Solution {
public double findMaxAverage(int[] nums, int k) {
if(nums == null || nums.length < k){
return 0;
}
double sum = 0,max = Integer.MIN_VALUE;
int count = 0;
//i指的是右边界的可能位置,故最大值是nums.length - 1
for(int i = 0;i < nums.length;i++){
//右边新的元素进入窗口
sum += nums[i];
//初始化窗口时,窗口大小不足k则扩充
if(i < k - 1){
continue;
}
//更新最大值
max = sum > max ? sum : max;
//最左边元素离开窗口
sum -= nums[i - k + 1];
}
return max / k;
}
}
时间复杂度O(n),空间复杂度O(1)

1158

被折叠的 条评论
为什么被折叠?



