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. 开启Centos系统的SSH服务

    1.登录Centos6.4系统. ◆示例:使用root用户登录. 注:若为非root用户登录,输入执行某些命权限不够时需加sudo. 查看SSH是否安装. 2.◆输入命令:rpm -qa | grep ...

  2. nginx反向代理:两个域名指向不同web服务端口

    一台服务器上安装了zabbix服务和jumpserver服务,两个域名zabbix.xxxx.xxxx和jumserver.xxx.xxxx 一.编辑/etc/nginx/conf.d目录下nginx ...

  3. Linux yum安装MySQL5.7

    一.安装配置MySQL的yum源 # 安装MySQL的yum源,下面是RHEL6系列的下载地址 rpm -Uvh http://dev.mysql.com/get/mysql-community-re ...

  4. Tomcat添加管理员role

       最近朋友问我怎么在Tomcat里面使用 admin 登录,一般情况下登录后是提示xxx的,经过百度后,好不容易才找到答案:    原来添加一个role为admin:<role rolena ...

  5. AdminLTE 侧边栏收缩时触发的事件

    点击此处,会触发 expanded.pushMenu 或 collapsed.pushMenu 事件 如果需要在事件触发时编写相关逻辑,可用如下方式 $("body").on(&q ...

  6. DHCP server 冒充及DOS攻击处理方案

    一.DHCP服务器在运维上存在的常见问题: 1. DHCP服务器冒充 在DHCP服务器和客户端之间没有认证机制,如果在DHCP server覆盖的网络上随意接入一个DHCP server,就有可能造成 ...

  7. TOJ 4976: 新生数(深搜)

    传送门:http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=4976 时间限制(普通/Java): ...

  8. maven 常用参数使用详解

    前言 作为java开发按人员,使用maven构建似乎成为了工作中平常的事情,但有时会遇到一些问题,感到困惑,于是我整理出来,方便其他同学更好的使用,以后会慢慢更新这个文章. 命令介绍 -DskipTe ...

  9. vue生产环境部署总结

    参考:http://www.cnblogs.com/vipstone/p/6910255.html 1. vue项目根目录/config/index.js更改资源生成路径 assetsPublicPa ...

  10. ubuntu下安装nginx1.11.10

    (本页仅作为个人笔记参考) 为openssl,zlib,pcre配置编译 wget http://om88fxbu9.bkt.clouddn.com/package/nginx/nginx-1.11. ...