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:计算子数组之后的常用方法是建立累加数组,然后再计算任意一定长度 ...
随机推荐
- appium自动化测试之UIautomatorviewer元素定位
appium自动化测试之UIautomatorviewer元素定位 标签(空格分隔): uiautomatorviewer元素定位 前面的章节,已经总结了怎么搭建环境,怎样成功启动一个APP了,这里具 ...
- Oracle数据导出导入
总结了几种Oracle导入导出的命令方法,方便以后使用. 数据导出: 1. 将数据库test完全导出,用户名system 密码manager 导出到d:/daochu.dmp中 ...
- js setInterval参数设置
语法 setInterval(code,interval) ①可以有第三个参数,第三个参数作为第一个参数(函数)的参数 ②第一个参数是函数,有三种形式: 1.传函数名,不用加引号,也不加括号,如 s ...
- ELK Deployed
Enviroment prepare rpm -qa | grep java wget http://download.oracle.com/otn-pub/java/jdk/8u171-b11/51 ...
- UVA-816.Abbott's Tevenge (BFS + 打印路径)
本题大意:给定一个迷宫,让你判断是否能从给定的起点到达给定的终点,这里起点需要输入起始方向,迷宫的每个顶点也都有行走限制,每个顶点都有特殊的转向约束...具体看题目便知... 本题思路:保存起点和终点 ...
- vcenter或workstation12导入ovf出错:硬件系列vmx 14不受支持
原因是因为导出ovf的虚拟机版本太高. 两个方法,一个强制,一个推荐. 强制 1. 打开ovf后缀文件,把<vssd:VirtualSystemType>vmx-14</vssd:V ...
- bbs项目中的零碎点记录
一.切换django的语言 在settings中修改django默认的语言 # LANGUAGE_CODE = 'en-us' # 切换django的语言,默认是英语的,我们把他修改为中文 LANGU ...
- java 线程Thread 技术--1.5Lock 与condition 演示生产者与消费模式
在jdk 1.5 后,Java 引入了lock 锁来替代synchronized ,在使用中,lock锁的使用更加灵活,提供了灵活的 api ,不像传统的synchronized ,一旦进入synch ...
- java 线程Thread 技术--线程方法详解
Thread 类常用的方法与Object类提供的线程操作方法:(一个对象只有一把锁
- day 12 内置函数,装饰器,递归函数
内置函数 内置函数:python给咱们提供了一些他认为你会经常用到的函数,68种 内置函数 abs() dict() help() min() setattr() all() di ...