zoukankan      html  css  js  c++  java
  • 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;
        }
    }
  • 相关阅读:
    E:Could not get lock /var/lib/apt/lists/lock
    报错:shell-init: error retrieving current directory: getcwd: cannot access parent directories
    随记
    Linux下C++调用后端接口
    Python操作Execl
    使用CamFI设备二次开发,传输照片遇到的问题
    “Could not determine which "make" command to run. Check the "make" step in the build configuration.” 在Linux下 Qt图形库出错解决
    在Linux系统下Qt中获取相对路径
    C++命名空间
    css知识点汇总
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7636531.html
Copyright © 2011-2022 走看看