• 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;
        }
    }
  • 相关阅读:
    解决ubuntu不能安装g++的问题
    解决VMware虚拟机不能上网的问题
    打开vmvare出现The VMware Authorization Service is not running。
    word2-寻找社交新浪微博中的目标用户
    新浪云计算SAE部署代码过程
    Python如何调用新浪api接口的问题
    work1-英语辅导班在线报名系统
    Mysql对自增主键ID进行重新排序
    如何使用LIBSVM,从安装到基本实例使用
    laravel怎么创建一个简单的blog
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7636531.html
Copyright © 2020-2023  润新知