lintcode617- Maximum Average Subarray- medium

Posted jasminemzy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lintcode617- Maximum Average Subarray- medium相关的知识,希望对你有一定的参考价值。

Given an array with positive and negative numbers, find the maximum average subarray which length should be greater or equal to given length k.

 Notice

It‘s guaranteed that the size of the array is greater or equal to k.

Example

Given a binary tree:

     1
   /    -5     11
 / \   /  1   2 4    -2 

return the node 11.

 

 

二分法做,一开始你就假设一个average在最大值和最小值的中间,然后看这个average合不合格,小了去右半找,大了去左半找。

合不合格的函数里,先存一个sum数组,保存前i个num - average的和,这样sum[n]-sum[m]就代表(n~m这几个连续数字各自与ave的差值)的和。如过出现了sum[n]-sum[m] > 0的情况,就说明你的average其实可以取得更大来获得一个更好的最大值。

这个函数里还可以进一步优化从n方判断函数变为n判断函数。针对某个具体的sum[i],你可以跟的被减数一定要跟i隔了k个以上,也就是被减数index在i-k或之前。那么你只要试着找到sum[0]~sum[i-k]之间的最小数来作为减数就好了,因为如果这个最小数都不行,其他数就更不可能做到让sum[i]-减数>0了!所以一直用一个min_pre的变量来保存sum[0]~sum[i-k]之间的最小值,每次随着i变大不断更新该数字。

部分解释可见http://blog.csdn.net/qq_34153219/article/details/56298842

 

九章实现:

public class Solution {
    /**
     * @param nums an array with positive and negative numbers
     * @param k an integer
     * @return the maximum average
     */
    public double maxAverage(int[] nums, int k) {
        // Write your code here
        double l = Integer.MAX_VALUE, r = Integer.MIN_VALUE;
        for (int i = 0; i < nums.length; ++i) {
            if (nums[i] < l)
                l = nums[i];
            if (nums[i] > r)
                r = nums[i];
        }
        
       
        while (r - l >= 1e-6) {
            double mid = (l + r) / 2.0;

            if (check_valid(nums, mid, k)) {
                l = mid;
            }
            else {
                r = mid;
            }
        }

        return l;
    }
    
    private boolean check_valid(int nums[], double mid, int k) {
        int n = nums.length;
        double min_pre = 0;
        double[] sum = new double[n + 1];
        sum[0] = 0; 
        for (int i = 1; i <= n; ++i) {
            sum[i] = sum[i - 1] + nums[i - 1] - mid;
            if (i >= k && sum[i] - min_pre >= 0) {
                return true;
            }
            if (i >= k)
                min_pre = Math.min(min_pre, sum[i - k + 1]);
        }
        return false;
    }
}

 

我的实现(思路模仿了的):

public class Solution {
    /*
     * @param nums: an array with positive and negative numbers
     * @param k: an integer
     * @return: the maximum average
     */
    public double maxAverage(int[] nums, int k) {
        // write your code here
        if (nums == null) {
            return Double.NEGATIVE_INFINITY;
        }
        
        double left = Double.POSITIVE_INFINITY;
        double right = Double.NEGATIVE_INFINITY;
        for (int i = 0; i < nums.length; ++i) {
            if (nums[i] < left) {
                left = (double)nums[i];
            }
            if (nums[i] > right) {
                right = (double)nums[i];
            }
        }
        
        double eps = 1e-6;
        while (left + eps < right) {
            double mid = left + (right - left) / 2;
            if (canBigger(mid, nums, k)) {
                left = mid;
            } else {
                right = mid;
            }
        }
        
        return left;
    }
    
    private boolean canBigger(double avg, int[] nums, int k) {
        
        double[] sums = new double[nums.length];
        sums[0] = nums[0] - avg;
        for (int i = 1; i < sums.length; i++) {
            sums[i] = sums[i - 1] + nums[i] - avg;
        }
        
        double min_prev = 0;
        for (int i = k - 1; i < sums.length; i++) {
            if (sums[i] - min_prev >= 0) {
                return true;
            }
            min_prev = Math.min(min_prev, sums[i - k + 1]);
        }
        
        return false;
    }
}

 

以上是关于lintcode617- Maximum Average Subarray- medium的主要内容,如果未能解决你的问题,请参考以下文章

lintcode-medium-Maximum Subarray II

lintcode-easy-Maximum Depth of Binary Tree

[LintCode] Maximum Subarray 最大子数组

[LintCode] Maximum Gap 求最大间距

lintcode-medium-Binary Tree Maximum Path Sum

[LintCode] Create Maximum Number 创建最大数