643:Maximum Average Subarray I

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. 1 <= k <= n <= 30,000.
  2. 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 }
这种方法可以大大提高运行效率。

转载于:https://www.cnblogs.com/CoderZSL/p/7655989.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值