1. 程式人生 > >LC 644. Maximum Average Subarray II

LC 644. Maximum Average Subarray II

Given an array consisting of n integers, find the contiguous subarray whose length is greater than or equal to 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:
when length is 5, maximum average value is 10.8,
when length is 6, maximum average value is 9.16667.
Thus return 12.75.

 

Note:

  1. 1 <= k <= n <= 10,000.
  2. Elements of the given array will be in range [-10,000, 10,000].
  3. The answer with the calculation error less than 10-5 will be accepted.

求一個數組中長度大於等於K的子陣列的平均值的最大值。

我的AC解,這道題沒什麼思路,我只能暴力求解了,雖然AC但時間肯定長。

Runtime : 1240ms  Beats:5.63%

class Solution {
public:
    double findMaxAverage(vector<int>& nums, int k) {
      vector<int> B(nums.size()+1);
      B[0] = 0;
      for(int i=1; i<B.size();i++){
        B[i] = B[i-1] + nums[i-1];
      }
      double sum = (double)INT_MIN;
      
      if(nums.size() < k) return
0; for(int i=k; i<B.size(); i++){ for(int j=0; j+k<=i; j++){ if(B[i] - B[j] > sum * (i - j)){ sum = (double)(B[i]-B[j])/(i-j); } } } return sum; } };

 

這是網上的解法,利用的是二分查詢,但是這裡的二分查詢的判斷條件不一樣,是以平均值作為判斷條件。

我們要知道,一個數組的子陣列的平均值介於這個陣列最大值和最小值之間。因此可以將最大值和最小值的平均數mid作為判斷依據,如果存在某一個長度大於K的子陣列的平均數大於mid,那就說明

需要從mid和最大值之間繼續尋找。尋找次數是O(log(max + min)),每一次尋找都是遍歷一遍陣列O(n)。

那如何通過遍歷一遍陣列來尋找是否存在一個長度大於K的子陣列的平均數大於mid呢?先看程式碼,

Runtime: 72ms, Beats: 90.14%

 

 

整個程式結構right代表最大值,left代表最小值,整個程式大結構是一個while迴圈,判斷條件是right和left差值小於0.00001,意思就是找到了題目要求的值。

mid是最大值和最小值的平均數。

利用sum求得陣列累加和與mid的差值。因為我們想要比較長度大於K的所有陣列和mid的大小關係,其實只需要比較長度大於K的所有陣列中的最大值與mid的關係。

而這個最大值和mid的關係可以用sum > minsum來表示,sum > minsum <=> sum - minsum > 0 <=> Σnums[i] - i * mid - minsum > 0 這個式子減號前一部分的意義好理解,

就是前i個數組元素的和與i*mid的差,其實就是前i個數組元素的平均數與mid的差,minsum是第0個到第i-k個累加和中最小的一個和0的最小值,minsum初始值為0,

所以碰到任何在0到i-k之間大於0的累加和全部為0,因為此時能讓sum最大的情況是我把前i個元素都包括進來。

如果碰到minsum小於0,假設這個minsum的index是第j個,也就是說第0到j個的累加和是小於0的,那這個時候,第j到i的累加和是要大於第0到i的累加和的,因為我們去掉了一些

小於0的元素。取最小就是為了讓sum最大。所以我們能得到長度大於K的所有陣列的最大值與mid的關係。一旦得到了這個關係我們就知道他高於還是低於平均值mid,進而再

用二分查詢的思想迭代,得到最終的長度大於K的所有陣列的最大值。

後續:

1. 如果要求長度大於K的所有陣列的最小值怎麼辦?

修改二分查詢的時候right和left的賦值規則就行。很簡單了。