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. javascript 表格排序和表头浮动效果(扩展SortTable)

    前段时间一个项目有大量页面用到表格排序和表头浮动的效果,在网上找了几个表格排序的js代码,最后选择了 Stuart Langridge的SortTable,在SortTable基础上做了些扩展,加上了 ...

  2. c++中的类(class)-----笔记(类多态)

    1,多态是一种运行期绑定机制,通过这种机制,实现将函数名绑定到函数具体实现代码的目的.一个函数的名称与其入口地址是紧密相连的,入口地址是该函数在内存中的起始地址.如果对一个函数的绑定发生在运行时刻而非 ...

  3. 十:python 对象类型详解六:文件

    一:文件 1.简介:内置open 函数会创建一个python 文件对象,可以作为计算机上的一个文件链接.在调用open 之后,可以通过调用返回文件对象的方法来读写相关外部文件.文件对象只是常见文件处理 ...

  4. 批量执行命令(SSH)

    for a in {1..6} ; do scp /etc/hosts enc-bigdata0$a:/etc/hosts ; done

  5. 从尾到头打印链表(python)

    题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. # -*- coding:utf-8 -*- # class ListNode: # def __init__(self, ...

  6. 6. ZigZag Conversion (字符串的连接)

    The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...

  7. LAB3 整数相加

    //yuec2 Yue Cheng package lab3; public class Fraction { int numerator; int denominator; //obeject wi ...

  8. REUSE_ALV_FIELDCATALOG_MERGE

    作用: 根据程序中的数据内表结构,来自动生成FIELDCAT[]内表,不用定义宏或者Form来一个个加入,会根据内表结构所参照的词典类型来自动完成如表标题字段名的生成,得到大概的FIELDCAT[]后 ...

  9. 42-2017蓝桥杯b java

    1.购物单    小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞.    这不,XX大促销又来了!老板夫人开出了长长的购物单,都 ...

  10. ubuntu14.04 安装系统/搜狗/QT/qq/wps/CAJviewer

    1.安装ubuntu系统     http://jingyan.baidu.com/album/4dc40848491fc5c8d946f1b1.html?picindex=1 官方网站:    ht ...