//644
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 <= k <= n <= 10,000.
Elements of the given array will be in range [-10,000, 10,000].
The answer with the calculation error less than 10-5 will be accepted.
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
class Solution {
private:
bool check(vector<int>& nums,double mid,int k){
//nums[i]-mid+nums[i+1]-mid +...nums[j]-mid>=0
//update max_val=mid,while <=0,need check all possible
//change into sums[j]-sums[i]>=0,j-i>=k+1;min sums[i],
//max(sums[j]-sums[i])? 0 ,prev note min sums[i]
//sum[i]--[0...k],prev--[0...i-k],min_sum--[0...j](j<=i-k)
double sum=0,prev=0,min_sum=0;
for(int i=0;i<k;i++){
sum+=nums[i]-mid;
}
if(sum>=0){
return true;
}
for(int i=k;i<nums.size();i++){
sum+=nums[i]-mid;
prev+=nums[i-k]-mid;
min_sum=min(prev,min_sum);
if(sum>=min_sum){
return true;
}
}
return false;
}
public:
double findMaxAverage(vector<int>& nums, int k) {
double max_val=nums[0];
double min_val=nums[0];
for(int i=1;i<nums.size();i++){
max_val=max(max_val,(double)nums[i]);
min_val=min(min_val,(double)nums[i]);
}
double prev_mid=max_val,error=INT32_MAX;
while(error>0.00001){
double mid=(max_val+min_val)*0.5;
if(check(nums,mid,k)){
min_val=mid;
} else{
max_val=mid;
}
error=fabs(prev_mid-mid);
prev_mid=mid;
}
return min_val;
}
};
int main(){
int k=1;
int arr[]={1,12,-5,-6,50,3};
vector<int> vec(arr,arr+sizeof(arr)/sizeof(int));
cout<<Solution().findMaxAverage(vec,k)<<endl;
return 0;
}