最大平均(和)子串行

2021-08-11 01:27:55 字數 1419 閱讀 3368

描述

給定n個數的陣列,找到所有長度大於等於k的連續子陣列中平均值最大的那個。返回那個最大的平均值。

1 <= k <= n <= 10000,陣列中的元素在範圍[-10000, 10000]之間,最後返回的答案的誤差應在10^(-5)以內。

樣例

輸入:[1,12,-5,-6,50,3], k = 4

輸出:12.75

說明

長度為4的子陣列中,最大的平均值為12.75,(=(12 + -5 + -6 + 50)/4)

長度為5的子陣列中,最大的平均值為10.8,(=(12 + -5 + -6 + 50 + 3)/5)

長度為6的子陣列中,最大的平均值為9.16667。(所有數的平均值)

因此返回12.75。

分析

首先,考慮把求平均問題轉換為求和問題,實質上是一樣的,然後用二分列舉,求出最大和。關鍵在於轉換和二分,二分法此類題通用。求長度大於等於k的最大和子陣列比原問題容易的多,令s為b的字首和子陣列,即s(i)=b(0)+b(1)+……+b(i-1),且s(0)=0,那麼b(j)到b(i-1)的區間和可表示為s(i)-s(j)。

找長度大於等於k的最大和子陣列等價於找i,j,滿足i-j>=k,且使s(i)-s(j)最大。固定i,則要使s(i)-s(j)最大,s(j)應最小,同時也應滿足j<=i-k,令p(i) = min,j<=i-k,故 i 固定時s(i)-s(j)的最大值為s(i)-p(i),列舉所有i即可得到最終的最大值。

二分的初始區間可以設定為[min,i=0~n-1 , max,i=0~n-1],因為一組數的平均值不會小於這組數的最小值,也不會大於這組數的最大值。對於二分值a,通過前面講的方法以o(n)的時間判斷是否有子陣列的平均值大於等於a,若有則答案大於等於a,若沒有,則答案小於a。二分至區間長度小於所需精度,即可返回該值。

測試

#include

using namespace std;

class

solution

double

sum[n+1];

while(right-left>1e-6)

double premin=0;

double summax=int_min;

for(int i=k;i<=n;i++)

if(summax>=0)

else

}return left;

}};int main()

double result=sol.find(n,a,k);

cout0;}

若需繼續使用斜率優化,可以參考:

二分 最大平均子串行

為了讓俱樂部的孩子們放假在家學習,mxj特地為俱樂部的孩子們準備了乙個winter camp,在舉辦之前,mxj想讓大家熱熱身,於是讓大家報出了自己收到的壓歲錢數,並排成了乙個正整數序列a。題目描述 mxj會給你乙個長度len,讓你從這個整數序列a中找到長度大於等於len且平均數最大的乙個連續的子串...

子陣列最大平均數

給定 n 個整數,找出平均數最大且長度為 k 的連續子陣列,並輸出該最大平均數。示例 1 輸入 1,12,5,6,50,3 k 4 輸出 12.75 簡單的滑動視窗題目 直接暴力求解會導致時間複雜度過高,大量資料輸入超出最大執行時間 使用滑動視窗優化減少迴圈巢狀 1.初始前k個數的值sum 2.從第...

隨筆 連續子陣列最大平均數

題目 給定 n 個整數,找出平均數最大且長度為 k 的連續子陣列,並輸出該最大平均數。示例 1 輸入 1,12,5,6,50,3 k 4 輸出 12.75 解釋 最大平均數 12 5 6 50 4 51 4 12.75 注意 1 k n 30,000。所給資料範圍 10,000,10,000 思路 ...