您的位置:首页 > 其它

最大平均值子数组

2017-09-15 23:10 204 查看


最大平均值子数组 

 描述
 笔记

 数据

 评测

给出一个整数数组,有正有负。找到这样一个子数组,他的长度大于等于 
k
,且平均值最大。


 注意事项


保证数组的大小 >= k

您在真实的面试中是否遇到过这个题? 

Yes

样例

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

返回 
15.667
 // (-6 + 50
+ 3) / 3 = 15.667

   这道题可以用二分法去做。总结:所有有最大最小值去求某个值的题目,都可以用二分法。具体代码和解释见代码:
public double maxAverage(int[] nums, int k) {
double high = Integer.MIN_VALUE;
double low = Integer.MAX_VALUE;
for (int n : nums) {
if (high < n) {
high = n;
}
if (low > n) {
low = n;
}
}
// 1. 最大平均子数组的平均数一定小于数组最大值,大于数组最小值,用这个最大最小去逼近
while (high - low > 1e-6) {
double mid = (high + low) / 2;
if (hasBiggerSubArray(nums, k, mid)) {
low = mid;
} else {
high = mid;
}
}
return high;
}

private boolean hasBiggerSubArray(int[] nums, int k, double mid) {
double[] sum = new double[nums.length];
double min = 0;
sum[0] = nums[0] - mid;
for (int i = 1; i < nums.length; i++) {
sum[i] = sum[i - 1] + nums[i] - mid;
if (i >= k - 1 && sum[i] > min) {//
return true;
}
if (i >= k - 1) {
// 2.求i前面且距离i大于等于长度k的某个偏差最小值。
// 2.1为啥找前面最小偏差呢:假定这个值为nums[j],如果这个最小偏差被后面某个偏差加大了,说明j到i这个子数组里面存在平均数比
// mid大的,只有i到j的平均数比mid大才会使得sum[i] > sum[j](如果比mid小,sum只会越加越小);这步是这个算法的重难点
// 2.2为啥长度要大于k才执行此逻辑:确保2.1中说的加大了偏差的子数组的长度大于等于k
min = Math.min(min, sum[i - k + 1]);
}
}
return false;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: