You are given an integer array nums consisting of n elements, and an integer k.
Find a contiguous subarray whose length is greater than or equal tok
that has the maximum average value and return this value. Any answer with a calculation error less than 10-5 will be accepted.
Input: nums =[1,12,-5,-6,50,3], k =4Output: 12.75000Explanation: - When the length is4, averages are [0.5,12.75,10.5] and the maximum average is12.75- When the length is5, averages are [10.4,10.8] and the maximum average is10.8- When the length is6, averages are [9.16667] and the maximum average is9.16667The maximum average is when we choose a subarray of length 4(i.e., the sub array [12,-5,-6,50]) which has the max average 12.75, so we return12.75Note that we do not consider the subarrays of length <4.
To find the maximum average subarray of length at least k, we can use binary search on the answer. For a candidate average, we check if there exists a subarray of length at least k whose average is at least that value. This can be checked using prefix sums and maintaining the minimum prefix sum for the window.
classSolution {
public:double findMaxAverage(vector<int>& nums, int k) {
double l =*min_element(nums.begin(), nums.end()), r =*max_element(nums.begin(), nums.end());
while (r - l >1e-5) {
double m = (l + r) /2;
vector<double> s(nums.size()+1);
for (int i =0; i < nums.size(); ++i) s[i+1] = s[i] + nums[i] - m;
double min_pre =0, ok =0;
for (int i = k; i <= nums.size(); ++i) {
if (s[i] - min_pre >=0) ok =1;
min_pre = min(min_pre, s[i-k+1]);
}
if (ok) l = m; else r = m;
}
return l;
}
};
funcfindMaxAverage(nums []int, kint) float64 {
l, r:= float64(nums[0]), float64(nums[0])
for_, x:=rangenums {
if float64(x) < l { l = float64(x) }
if float64(x) > r { r = float64(x) }
}
forr-l > 1e-5 {
m:= (l+r) /2s:= make([]float64, len(nums)+1)
fori:=0; i < len(nums); i++ {
s[i+1] = s[i] + float64(nums[i]) -m }
minPre, ok:=0.0, falsefori:=k; i<= len(nums); i++ {
ifs[i]-minPre>=0 {
ok = true }
ifs[i-k+1] < minPre {
minPre = s[i-k+1]
}
}
ifok {
l = m } else {
r = m }
}
returnl}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution {
publicdoublefindMaxAverage(int[] nums, int k) {
double l = Arrays.stream(nums).min().getAsInt(), r = Arrays.stream(nums).max().getAsInt();
while (r - l > 1e-5) {
double m = (l + r) / 2;
double[] s =newdouble[nums.length+1];
for (int i = 0; i < nums.length; ++i) s[i+1]= s[i]+ nums[i]- m;
double minPre = 0;
boolean ok =false;
for (int i = k; i <= nums.length; ++i) {
if (s[i]- minPre >= 0) ok =true;
minPre = Math.min(minPre, s[i-k+1]);
}
if (ok) l = m; else r = m;
}
return l;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution {
funfindMaxAverage(nums: IntArray, k: Int): Double {
var l = nums.minOrNull()!!.toDouble()
var r = nums.maxOrNull()!!.toDouble()
while (r - l > 1e-5) {
val m = (l + r) / 2val s = DoubleArray(nums.size+1)
for (i in nums.indices) s[i+1] = s[i] + nums[i] - m
var minPre = 0.0var ok = falsefor (i in k..nums.size) {
if (s[i] - minPre >=0) ok = true minPre = minOf(minPre, s[i-k+1])
}
if (ok) l = m else r = m
}
return l
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution:
deffindMaxAverage(self, nums: list[int], k: int) -> float:
l, r = min(nums), max(nums)
while r - l >1e-5:
m = (l + r) /2 s = [0]
for x in nums:
s.append(s[-1] + x - m)
min_pre =0 ok =Falsefor i in range(k, len(nums)+1):
if s[i] - min_pre >=0:
ok =True min_pre = min(min_pre, s[i-k+1])
if ok:
l = m
else:
r = m
return l
impl Solution {
pubfnfind_max_average(nums: Vec<i32>, k: i32) -> f64 {
let (mut l, mut r) = (*nums.iter().min().unwrap() asf64, *nums.iter().max().unwrap() asf64);
while r - l >1e-5 {
let m = (l + r) /2.0;
letmut s =vec![0.0; nums.len()+1];
for i in0..nums.len() {
s[i+1] = s[i] + nums[i] asf64- m;
}
letmut min_pre =0.0;
letmut ok =false;
for i in k asusize..=nums.len() {
if s[i] - min_pre >=0.0 {
ok =true;
}
min_pre = min_pre.min(s[i-k asusize+1]);
}
if ok {
l = m;
} else {
r = m;
}
}
l
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution {
findMaxAverage(nums: number[], k: number):number {
letl= Math.min(...nums), r= Math.max(...nums);
while (r-l>1e-5) {
constm= (l+r) /2;
consts= [0];
for (constxofnums) s.push(s[s.length-1] +x-m);
letminPre=0, ok=false;
for (leti=k; i<=nums.length; ++i) {
if (s[i] -minPre>=0) ok=true;
minPre= Math.min(minPre, s[i-k+1]);
}
if (ok) l=m; elser=m;
}
returnl;
}
}