Description
Given an array consisting of n integers, find the contiguous subarray of given length k that has the maximum average value. And you need to output the maximum average value.
Example
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
Note
- 1 <= k <= n <= 30,000.
- Elements of the given array will be in the range [-10,000, 10,000].
Solution
这道题要求求出连续k位数的最大平均值,本质上就是求出连续k位数的最大和。最直观的解法是从i=0开始,将连续k位相加并与最大值max作比较,然后将i往后移一位继续计算连续k位的和,直到连续k位数的最后一位数下标超过了边界。这种思路的代码如下:
public class Solution {
public double findMaxAverage(int[] nums, int k) {
int max = Integer.MIN_VALUE;
int i = 0;
while(i + k - 1 < nums.length) {
int curr = 0;
int j = i;
int cnt = k;
while(cnt-- > 0) {
curr += nums[j];
j++;
}
if(curr > max)
max = curr;
i++;
}
return (double)max / k;
}
}
但这种解法的运行时间并不理想,甚至超过了1s,因此需要改进。我们以int[] nums = {1, 12, -5, -6, 50, 3}, k = 4
为例,第一个连续的四位数为1, 12, -5, -6
,而第二个连续的四位数为12, -5, -6, 50
,可以看出在第一种思路中,我们不必要地重复计算了12, -5, -6
,而实际上我们只用比较第一个连续四位数的第一个数字和第二个连续四位数的第二个数字即可。改进后的代码如下:
class Solution {
public double findMaxAverage(int[] nums, int k) {
int sum = 0;
for(int i = 0; i < k; i++) {
sum += nums[i];
}
int max = sum;
for(int i = k; i < nums.length; i++) {
sum += nums[i] - nums[i-k];
if(sum > max)
max = sum;
}
return (double)max / k;
}
}