描述
给定n个数的数组,找到所有长度大于等于k的连续子数组中平均值最大的那个。返回那个最大的平均值。
1 <= k <= n <= 10000,数组中的元素在范围[-10000, 10000]之间,最后返回的答案的误差应在10^(-5)以内。
样例
输入:[1,12,-5,-6,50,3], k = 4
输出:12.75
说明
长度为4的子数组中,最大的平均值为12.75,(=(12 + -5 + -6 + 50)/4)
长度为5的子数组中,最大的平均值为10.8,(=(12 + -5 + -6 + 50 + 3)/5)
长度为6的子数组中,最大的平均值为9.16667。(所有数的平均值)
因此返回12.75。
分析
首先,考虑把求平均问题转换为求和问题,实质上是一样的,然后用二分枚举,求出最大和。关键在于转换和二分,二分法此类题通用。求长度大于等于k的最大和子数组比原问题容易的多,令s为b的前缀和子数组,即s(i)=b(0)+b(1)+……+b(i-1),且s(0)=0,那么b(j)到b(i-1)的区间和可表示为s(i)-s(j)。
找长度大于等于k的最大和子数组等价于找i,j,满足i-j>=k,且使s(i)-s(j)最大。固定i,则要使s(i)-s(j)最大,s(j)应最小,同时也应满足j<=i-k,令p(i) = min{s(j)},j<=i-k,故 i 固定时s(i)-s(j)的最大值为s(i)-p(i),枚举所有i即可得到最终的最大值。
二分的初始区间可以设置为[min{a(i)},i=0~n-1 , max{a(i)},i=0~n-1],因为一组数的平均值不会小于这组数的最小值,也不会大于这组数的最大值。对于二分值A,通过前面讲的方法以O(n)的时间判断是否有子数组的平均值大于等于A,若有则答案大于等于A,若没有,则答案小于A。二分至区间长度小于所需精度,即可返回该值。