LintCode 最大平均值子数组
2017-10-23 17:10
337 查看
给出一个整数数组,有正有负。找到这样一个子数组,他的长度大于等于 k,且平均值最大。
注意事项
保证数组的大小 >= k
样例
给出 nums = [1, 12, -5, -6, 50, 3], k = 3
返回 15.667 // (-6 + 50 + 3) / 3 = 15.667
参考了别人的想法,利用二分法,依然不是对数组中元素的二分,而是对一个区间的二分,逐渐找到结果。题目所求平均值一定是在 数组中最小值min和最大值max之间的一个数,所以对区间[min,max]二分查找。
如何判断是在mid左侧继续查找还是右侧继续查找,我们需要判断对于当前的假设结果mid(即假设的平均值),在数组中是否存在一个长度大于等于k的子数组,其平均值比mid大。当然不能枚举,我们用一个辅助数组d,把原数组中每个数与mid的差的前缀和存储起来(利用前缀和的问题还有这个最接近零的子数组和),如果数组d中,存在d[i]-d[j]>=0,而且i-j>=k ,那么说明原数组nums[j] 到nums[i] 这个子数组的平均值大于等于mid,接下来就要在[mid,max]中继续找,否则在[min,mid]中继续找。在判断d[i]-d[j]>=0时,我们用一个最小是preMin来代替d[j],preMin指的是数组d中,在d[i]之前,并且满足i-j>=k的最小值。(因为我们要判断是否存在一个误差大于0,所以我们只关心任意两个误差前缀和相减之后的最大值,所以那个被减数越小越好)。
代码如下:
注意事项
保证数组的大小 >= k
样例
给出 nums = [1, 12, -5, -6, 50, 3], k = 3
返回 15.667 // (-6 + 50 + 3) / 3 = 15.667
参考了别人的想法,利用二分法,依然不是对数组中元素的二分,而是对一个区间的二分,逐渐找到结果。题目所求平均值一定是在 数组中最小值min和最大值max之间的一个数,所以对区间[min,max]二分查找。
如何判断是在mid左侧继续查找还是右侧继续查找,我们需要判断对于当前的假设结果mid(即假设的平均值),在数组中是否存在一个长度大于等于k的子数组,其平均值比mid大。当然不能枚举,我们用一个辅助数组d,把原数组中每个数与mid的差的前缀和存储起来(利用前缀和的问题还有这个最接近零的子数组和),如果数组d中,存在d[i]-d[j]>=0,而且i-j>=k ,那么说明原数组nums[j] 到nums[i] 这个子数组的平均值大于等于mid,接下来就要在[mid,max]中继续找,否则在[min,mid]中继续找。在判断d[i]-d[j]>=0时,我们用一个最小是preMin来代替d[j],preMin指的是数组d中,在d[i]之前,并且满足i-j>=k的最小值。(因为我们要判断是否存在一个误差大于0,所以我们只关心任意两个误差前缀和相减之后的最大值,所以那个被减数越小越好)。
代码如下:
ublic 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 max=nums[0],min=nums[0]; for(int x: nums){ if(x>max){ max=x; } if(x<min){ min=x; } } double avg=0.0; while(max-min>1e-6){ boolean flag=false; avg=min+(max-min)/2.0; double[] d =new double[nums.length+1]; d[0]=0.0;//数组d中d[0]存0,d[1]存nums中第1个数与avg的差... double preMin=d[0]; for(int i=1;i<=nums.length;i++){ d[i]=d[i-1]+nums[i-1]-avg; if(i>=k && d[i]-preMin>=0){ flag=true; break; } if(i>=k){ preMin=Math.min(preMin,d[i-k+1]); } } if(flag){ min=avg; } else{ max=avg; } } return min; } }
相关文章推荐
- LintCode求最大平均值子数组
- 最大平均值子数组-LintCode
- [置顶] lintcode(617)最大平均值子数组
- lintcode-42-最大子数组 II
- lintcode 最大子数组III
- lintcode最大子数组
- Lintcode:最大子数组
- 最大平均值子数组
- lintcode--45. 最大子数组差
- [LintCode] Maximum Subarray 最大子数组
- 算法爱好者——最大平均值子数组 ? 待解决
- 最大子数组 II-LintCode
- LintCode-41. 最大子数组
- lintcode(42)最大子数组 II
- LintCode 最大子数组(dp)
- LintCode 最大子数组(3种方法)
- Lintcode 41.最大子数组
- LintCode 第41题 最大子数组
- LintCode:最大子数组 II
- Lintcode 最大子数组 II