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. 1 <= k <= n <= 10,000.
  2. Elements of the given array will be in range [-10,000, 10,000].
  3. 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的更多相关文章

  1. leetcode644. Maximum Average Subarray II

    leetcode644. Maximum Average Subarray II 题意: 给定由n个整数组成的数组,找到长度大于或等于k的连续子阵列,其具有最大平均值.您需要输出最大平均值. 思路: ...

  2. [LeetCode] Maximum Average Subarray II 子数组的最大平均值之二

    Given an array consisting of n integers, find the contiguous subarray whose length is greater than o ...

  3. [LeetCode] 644. Maximum Average Subarray II 子数组的最大平均值之二

    Given an array consisting of n integers, find the contiguous subarray whose length is greater than o ...

  4. Maximum Average Subarray II

    Description Given an array with positive and negative numbers, find the maximum average subarray whi ...

  5. 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 ...

  6. 643. Maximum Average Subarray I 最大子数组的平均值

    [抄题]: Given an array consisting of n integers, find the contiguous subarray of given length k that h ...

  7. LeetCode 643. 子数组最大平均数 I(Maximum Average Subarray I)

    643. 子数组最大平均数 I 643. Maximum Average Subarray I 题目描述 给定 n 个整数,找出平均数最大且长度为 k 的连续子数组,并输出该最大平均数. LeetCo ...

  8. Maximum Average Subarray

    Given an array with positive and negative numbers, find the maximum average subarray which length sh ...

  9. 【Leetcode_easy】643. Maximum Average Subarray I

    problem 643. Maximum Average Subarray I 题意:一定长度的子数组的最大平均值. solution1:计算子数组之后的常用方法是建立累加数组,然后再计算任意一定长度 ...

随机推荐

  1. JMeter学习(二十四)HTTP属性管理器HTTP Cookie Manager、HTTP Request Defaults(转载)

    转载自 http://www.cnblogs.com/yangxia-test Test Plan的配置元件中有一些和HTTP属性相关的元件:HTTP Cache Manager.HTTP Autho ...

  2. tomcat端口被占用 实际上却查询不到此端口

    参考 http://www.cnblogs.com/jieliujas/p/9413064.html 1.打开PCHunter,在进程选项卡下面可以找到无法结束的进程,右键--强制结束,失败(这儿效果 ...

  3. 解决 HDFS 开发 java.lang.IllegalArgumentException: java.net.UnknownHostException: hadoop000

    出现这种问题多半是windows找不到linux主机所以在 这个路径下的hosts加上linux ip地址,主机名就可以了

  4. linux环境下的c++编程

    就C++开发工具而言,与Windows下微软(VC, VS2005等)一统天下相比,Linux/Unix下C++开发,可谓五花八门,各式各样.Emacs, vi, eclipse, anjuta,kd ...

  5. JavaScript各种继承方式(三):组合继承(combination inheritance)

    一 原理 组合继承仅仅是同时使用了原型链继承和构造函数继承. 具体做法是,将父类的实例作为子类的构造函数的原型对象,并在子类的构造函数中调用父类的构造函数. function Fruit(name){ ...

  6. [剑指Offer]25-合并两个排序链表

    题目链接 https://www.nowcoder.com/practice/d8b6b4358f774294a89de2a6ac4d9337?tpId=13&tqId=11169&t ...

  7. c#控件的动画显示效果

    1.  缘由: 项目中任务完成有个提示,需要以动画效果展示,其效果当如下图: 此为老项目为Delphi所写,改用c#实现,此效果做些设计.本也不难,小技而已,但为易于扩展,写了个静态类实现. 2. A ...

  8. 项目总结11:Centos部署JDK+Tomcat+MySQL文档(阿里云-网易云-华为云)

      (如果不是root登陆,则输入:sudo su - 切换成root) 1.JDK安装 1-1-yum update (升级所有包同时也升级软件和系统内核) --安装中会有提示输入y就好(两个y,中 ...

  9. 8.16 val()和html()的问题

    今天在做关闭模态框重置表单时,关闭模态框后输入框里的值还是在,不知道怎么回事? 感谢wd啦,原来我在初始化这个输入框的时候就写错了,输入框写值的时候用的是val(),而我和上面的div一样,用的是ht ...

  10. Java基本语法之动手动脑

    1.枚举类型 运行EnumTest.java 运行结果:false,false,true,SMALL,MEDIUM,LARGE 结论:枚举类型是引用类型,枚举不属于原始数据类型,它的每个具体值都引用一 ...