Maximum Average Subarray II LT644
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.
Idea 1. Brute force, use the idea on maximum subarray(Leetcode 53), for any pairs (i, j), j - i >= k-1, 0 <= i <= j < nums.length, check whether the sum of nums[i..j] is greater than the maximum sum so far.
Time complexity: O(n2)
Space complexity: O(1)
public class Solution {
public double findMaxAverage(int[] nums, int k) {
double maxAverage = Integer.MIN_VALUE; for(int i = 0; i < nums.length; ++i) {
double sum = 0;
for(int j = i; j < nums.length; ++j) {
sum += nums[j];
if(j-i + 1 >= k) {
maxAverage = Math.max(maxAverage, sum/(j-i+1));
}
}
} return maxAverage;
}
}
Idea 1.a Brute force, use the idea on Maximum Average Subarray I (Leetcode 643). Linearly find all the maximum average subarray for subarray length >= k.
public class Solution {
public double findMaxAverageWithLengthK(int[] nums, int k) {
double sum = 0;
for(int i = 0; i < k; ++i) {
sum += nums[i];
} double maxSum = sum;
for(int i = k; i < nums.length; ++i) {
sum = sum + nums[i] - nums[i-k];
maxSum = Math.max(maxSum, sum);
} return maxSum/k;
}
public double findMaxAverage(int[] nums, int k) {
double maxAverage = Integer.MIN_VALUE; for(int i = k; i < nums.length; ++i) {
double average = findMaxAverageWithLengthK(nums, i);
maxAverage = Math.max(maxAverage, average);
} return maxAverage;
}
}
Idea 2. Smart idea, use two techniques
1. Use binary search to guess the maxAverage, minValue in the array <= maxAverage <= maxValue in the array, assumed the guesed maxAverage is mid, if there exists a subarray with length >= k whos average is bigger than mid, then the maxAverage must be located between [mid, maxValue], otherwise between [minValue, mid].
2. How to efficiently check if there exists a subarray with length >= k whos average is bigger than mid? do you still remember the cumulative sum in maximum subArray? maximum sum subarray with length >= k can be computed by cumu[j] - min(cumu[i]) where j - i + 1 >= 0. If we deduct each element with mid (nums[i] -mid), the problem is transfered to find if there exists a subarray whoes sum >= 0. Since this is not strictly to find the maxSum, in better case if any subarray's sum >= 0, we terminate the search early and return true; in worst case we search all the subarray and find the maxmum sum, then check if maxSum >= 0.
Time complexity: O(nlogn)
Space complexity: O(1)
public class Solution {
private boolean containsAverageArray(List<Integer> nums, double targetAverage, int k) {
double sum = 0;
for(int i = 0; i < k; ++i) {
sum += nums.get(i) - targetAverage;
} if(sum >= 0) return true; double previousSum = 0;
double minPreviousSum = 0;
double maxSum = -Double.MAX_VALUE;
for(int i = k; i < nums.size(); ++i) {
sum += nums.get(i) - targetAverage;
previousSum += nums.get(i-k) - targetAverage;
minPreviousSum = Math.min(minPreviousSum, previousSum);
maxSum = Math.max(maxSum, sum - minPreviousSum);
if (maxSum >= 0) {
return true;
}
} return false;
} public double findMaxAverage(List<Integer> nums, int k) { double minItem = Collections.min(nums);
double maxItem = Collections.max(nums); while(maxItem - minItem >= 1e-5 ) {
double mid = minItem + (maxItem - minItem)/2.0; boolean contains = containsAverageArray(nums, mid, k);
if (contains) {
minItem = mid;
}
else {
maxItem = mid;
} } return maxItem;
}
}
We can reduce one variable, maxSum, terminate if sum - minPrevious >= 0, sum - minPreviousSum is the maxSum ended at current index.
a. sum - minPrevious < 0 if maxSum > sum - minPrevious, maxSum < 0 in previous check
b. sum - minPrevious < 0 if maxSum < sum -minPrevious < 0
c. sum - minPrevious > 0 if maxSum < 0 < sum - minPrevious
public class Solution {
private boolean containsAverageArray(List<Integer> nums, double targetAverage, int k) {
double sum = 0; for(int i = 0; i < k; ++i) {
sum += nums.get(i) - targetAverage;
}
if(sum >= 0) return true; double previousSum = 0;
double minPreviousSum = 0;
for(int i = k; i < nums.size(); ++i) {
sum += nums.get(i) - targetAverage;
previousSum += nums.get(i-k) - targetAverage;
minPreviousSum = Math.min(minPreviousSum, previousSum);
if(sum >= minPreviousSum ) {
return true;
}
} return false;
} public double findMaxAverage(List<Integer> nums, int k) { double minItem = Collections.min(nums);
double maxItem = Collections.max(nums); while(maxItem - minItem >= 1e-5 ) {
double mid = minItem + (maxItem - minItem)/2.0; boolean contains = containsAverageArray(nums, mid, k);
if (contains) {
minItem = mid;
}
else {
maxItem = mid;
} } return maxItem;
} }
Idea 3. There is a O(n) solution listed on this paper section 3 (To read maybe)
https://arxiv.org/pdf/cs/0311020.pdf
Maximum Average Subarray II LT644的更多相关文章
- leetcode644. Maximum Average Subarray II
leetcode644. Maximum Average Subarray II 题意: 给定由n个整数组成的数组,找到长度大于或等于k的连续子阵列,其具有最大平均值.您需要输出最大平均值. 思路: ...
- [LeetCode] Maximum Average Subarray II 子数组的最大平均值之二
Given an array consisting of n integers, find the contiguous subarray whose length is greater than o ...
- [LeetCode] 644. Maximum Average Subarray II 子数组的最大平均值之二
Given an array consisting of n integers, find the contiguous subarray whose length is greater than o ...
- Maximum Average Subarray II
Description Given an array with positive and negative numbers, find the maximum average subarray whi ...
- LC 644. Maximum Average Subarray II 【lock,hard】
Given an array consisting of n integers, find the contiguous subarray whose length is greater than o ...
- 643. Maximum Average Subarray I 最大子数组的平均值
[抄题]: Given an array consisting of n integers, find the contiguous subarray of given length k that h ...
- LeetCode 643. 子数组最大平均数 I(Maximum Average Subarray I)
643. 子数组最大平均数 I 643. Maximum Average Subarray I 题目描述 给定 n 个整数,找出平均数最大且长度为 k 的连续子数组,并输出该最大平均数. LeetCo ...
- Maximum Average Subarray
Given an array with positive and negative numbers, find the maximum average subarray which length sh ...
- 【Leetcode_easy】643. Maximum Average Subarray I
problem 643. Maximum Average Subarray I 题意:一定长度的子数组的最大平均值. solution1:计算子数组之后的常用方法是建立累加数组,然后再计算任意一定长度 ...
随机推荐
- Spring <tx:annotation-driven>注解 JDK动态代理和CGLIB动态代理 区别。
基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别. 我还是喜欢基于Schema风格的Spring事务管理,但也有很多人在用基于@Tras ...
- springboot 集成 redis
导入maven依赖 <!-- springboot整合 redis --> <dependency> <groupId>org.springframework.bo ...
- app.route()
[app.route()] 可使用 app.route() 创建路由路径的链式路由句柄.由于路径在一个地方指定,这样做有助于创建模块化的路由,而且减少了代码冗余和拼写错误.请参考 Router() 文 ...
- 分享一个 Java String split 快速分割的方法
java中string.split() 方法比较强大,但是split()方法采用正则表达式,速度相对会慢一点, 其实大多数场景下并不需要使用正则表达式,下面分享一个不使用正则表达式分隔字符串的方法. ...
- cdnbest的站点日志保存时间怎么设置
站点的保存时间是以节点全局里的保存时间为准 站点的日志保存大小还不能设置
- RedHat 更新CentOS Yum源(转)
经测试,可用.转自:https://www.cnblogs.com/tangsen/p/5151994.html 一.随笔引言 1.1随笔内容: 1.RedHat 配置Centos yum源 2.yu ...
- WAS 常见报错
1) An error occurred while deleting the server. ADMG0011E: An unexpected exception occurred com.ibm. ...
- jsp页面之初体验
最近在学jsp 在web.xml页面中学到了如何让一个页面第一个启动
- AltiumDesigner 网络标号放置技巧
我们在使用AD画图的过程中,灵活的使用一些小技巧可以使我们的工作事半功倍,今天给大家介绍一种在画原理图过程中的小技巧. 我们在画原理图过程中经常会放置网络标号,尤其是很多芯片管脚上,例如现在我需要在这 ...
- PHP: PCRE 函数- Manual
1.函数 http://php.net/manual/zh/ref.pcre.php 2.语法 http://www.runoob.com/regexp/regexp-tutorial.html