Maximum Average Subarray

http://www.lintcode.com/en/problem/maximum-average-subarray/

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

 

Example

Given nums = [1, 12, -5, -6, 50, 3], k = 3

Return 15.667 // (-6 + 50 + 3) / 3 = 15.667

 

GetWay: 1. mid shoule locate in the range of min & max.

2. checkValid could check mid value. if mid is too small return true else return false;

3. when the value of r & l are nearlly same, then the average value is gotten. 

4. in checkValid, sum[i] means that nums[i] - i * mid, cus it is in for loop, expression is diff.

5. preMin start with 0.0. after k index of nums, preMin should be checked. If the smaller value exists, then subsitute.

6. After k, sum[i] could be negtive, but sum[i] - preMin could be larger. And preMin constrained far away k index, such as sum[i - k + 1], it is nums[0] ~ nums[i - k] minus mid for every element.

 

Solution:

public double maxAverage(int[] nums, int k) {

  if (nums == null || nums.length == 0) {

    return 0.0;

  }

  double l = Double.MAX_VALUE;

  double r = Double.MIN_VALUE;

  double mid = 0.0;

  for (int i = 0; i < nums.length; i++) {

    if (nums[i] < l) {

      l = nums[i];

    }

    if (nums[r] > r) {

      r = nums[i];

    }

  }

  while (r - l >= 1e-6) {

    mid = l + (r - l) / 2.0;

    if (checkValid(nums, mid, k)) {

      l = mid;

    } else {

      r = mid;

    }

  }

  return l;

}

private boolean checkValid(int[] nums, double mid, int k) {

  if (nums == null || nums.length == 0) {

    System.out.println("checkValid function para error");

    return false;

  }

  int n = nums.length;

  double[] sum = new double[n + 1];

  sum[0] = 0.0;

  double preMin = 0.0;

  for (int i = 1; i <= n; i++) {

    sum[i] = sum[i - 1] + nums[i - 1] - mid;

    if (i >= k && sum[i] - preMin >= 0) {

      return true;

    }

    if (i > k) {

      preMin = Math.min(preMin, sum[i - k + 1]);

    }

  }

  return false;

}

 

转载于:https://www.cnblogs.com/setnull/p/7193775.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值