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 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
Note:
- 1 <=
k
<=n
<= 30,000. - Elements of the given array will be in the range [-10,000, 10,000].
题目的意思就是:给定一个数组,再给定一个数字k,k小于数组元素的个数,求数组中相邻k个元素的最大平均数
---------------------------------------------------------------------------------------------------------------
思路1:就是遍历数组,从第一个元素开始循环,在循环中再从当前这个元素起,求出k个元素的值,然后将这个数放入另一个数组,遍历结束后,再从这个数组中找出最大的数,求这个数的平均数。
1 double findMaxAverage(vector<int>& nums, int k) 2 { 3 vector<double> aver_total; //求所有相邻k个元素的和 4 int sum = 0; 5 for(int i = 0; i <= nums.size() - k; ++i) //第一次遍历,注意结束条件 6 { 7 for(int j = i; j < k + i; ++j) //当前元素下,k个元素求和的循环 8 { 9 sum += nums[j]; 10 } 11 aver_total.push_back(sum); //放入数组 12 sum = 0; //注意将sum置为0 13 } 14 return *max_element(aver_total.cbegin(), aver_total.cend())/(double)k; 15 //用标准库函数找到最大值,求平均值 16 }
但是这个方法首先新开辟了一个数组空间,其次两个for循环导致时间复杂度很高。
AC后看看时间1092ms,仅仅打败3%的人。。。
所以这肯定不是一种好方法
于是
思路二:
仔细想想,我们可以发现一个规律,从第一个元素开始,第一次k个元素的和,和第二次k个元素的和有什么差别?
其实,只是第一个元素和最后一个元素不一样,其余都是一样。
比如:数组[1,2,3,4,5,6],k = 4
第一次: 1 + 2 + 3 + 4
第二次: 2 + 3 + 4 + 5
第三次: 3 + 4 + 5 + 6
可以发现,下一次和上一次只有第一个元素和最后一个元素不一样,所以我们只需要改变一下第一个和最后一个元素的值,并把当前的值存下
1 double findMaxAverage(vector<int>& nums, int k) 2 { 3 int sum1 = accumulate(nums.cbegin(), nums.cbegin() + k, 0); 4 //调用标准库算法计算第一次k个元素的值 5 int sum2 = sum1; 6 for(int i = 1; i <= nums.size() - k; ++i) //循环从第二个元素开始 7 { 8 sum2 = sum2 - nums[i - 1] + nums[i + k - 1]; 9 //减去第一个元素,加上后一个元素 10 sum1 = max(sum1, sum2); //求出最大值保存 11 } 12 return sum1/(double)k; 13 }
这种方法可以大大提高运行效率。