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 <=
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.
// Brute Force
double findMaxAverage(vector<int>& nums, int k) { // time: O(n^2); space: O(n)
int n = nums.size();
vector<int> sums = nums;
for (int i = 1; i < n; ++i) sums[i] = sums[i - 1] + nums[i];
double res = (double)sums[k - 1] / k;
for (int i = k; i < n; ++i) {
double t = sums[i];
if (t > res * (i + 1)) res = t / (i + 1);
for (int j = i - k; j >= 0; --j) {
t = sums[i] - sums[j];
if (t > res * (i - j)) res = t / (i - j);
}
}
return res;
}
// Space Optimized Brute Force
double findMaxAverage(vector<int>& nums, int k) { // time: O(n^2); space: O(1)
double preSum = accumulate(nums.begin(), nums.begin() + k, 0);
double sum = preSum, res = sum / k;
for (int i = k; i < nums.size(); ++i) {
preSum += nums[i];
sum = preSum;
if (sum > res * (i + 1)) res = sum / (i + 1);
for (int j = 0; j <= i - k; ++j) {
sum -= nums[j];
if (sum > res * (i - j)) res = sum / (i - j);
}
}
return res;
}
// Binary Search
double findMaxAverage(vector<int>& nums, int k) { // time: O(nlogn); space: O(n)
int n = nums.size();
vector<double> sums(n + 1, 0.0);
double left = *min_element(nums.begin(), nums.end());
double right = *max_element(nums.begin(), nums.end());
while (left + 1e-5 < right) {
double mid = left + (right - left) / 2.0, pre_min_sum = 0.0;
bool mid_is_smaller = false;
for (int i = 1; i <= n; ++i) {
sums[i] = sums[i - 1] + (nums[i - 1] - mid);
if (i >= k) { // the sum in [j, i] interval is larger than 0, which means there is another max avg
pre_min_sum = min(pre_min_sum, sums[i - k]);
if (sums[i] > pre_min_sum) {
mid_is_smaller = true;
break;
}
}
}
if (mid_is_smaller) left = mid;
else right = mid;
}
return left;
}
// Space Optimized Binary Search
double findMaxAverage(vector<int>& nums, int k) { // time: O(nlogn); space: O(1)
double left = *min_element(nums.begin(), nums.end());
double right = *max_element(nums.begin(), nums.end());
while (left + 1e-5 < right) {
double mid = left + (right - left) / 2.0, sum = 0.0, preSum = 0.0, preMinSum = 0.0;
bool midIsSmaller = false;
for (int i = 0; i < nums.size(); ++i) {
sum += (nums[i] - mid);
if (i >= k) {
preSum += (nums[i - k] - mid);
preMinSum = min(preMinSum, preSum);
}
if (i >= k - 1 && sum > preMinSum) {
midIsSmaller = true;
break;
}
}
if (midIsSmaller) left = mid;
else right = mid;
}
return left;
}
Last updated
Was this helpful?