题目(LeetCode #644)
Given an array consisting of n
integers, find the contiguous subarray whose length is greater than or equal to k
that has the maximum average value. And you need to output the maximum average value.
Input: [1, 12, -5, -6, 50, 3], k = 4
Output: 12.75
Explanation:
when length is 5, maximum average value is 10.8,
when length is 6, maximum average value is 9.16667.
Thus return 12.75.
Note:
- 1 <=
k
<=n
<= 10,000. - Elements of the given array will be in range [-10,000, 10,000].
- The answer with the calculation error less than 10-5 will be accepted.
题解
本题的技巧性较强,可采用滑动窗口加二分法求解,用猜平均值的方式逼近真实值,实现的关键在于找到二分的条件。对于一个数组来说,其所有可能的子数组的最大平均值必介于最大值和最小值之间。取 mid = (min + max) / 2.0
,对数组依次求长度大于等于 k
的所有可能的子数组的平均值。若平均值序列中有值大于等于 mid
,则最大平均值必位于 [mid, max]
区间(即 l = mid
);若平均值序列中所有值都小于 mid
,则最大平均值必位于 [min, mid]
上(即 r = mid
)。其中,在计算平均值时,可将计算简化为 xi - mid 的和与 0 进行比较。
另一个 trick 是在计算数组所有可能的平均值时,不必对所有长度大于 k
的子数组再次进行遍历,只需在前 k
个元素和的基础上向右扩增,再减去前几项的和既可得到新的子数组的和。如 k = 4
,当滑动窗口中包含 0 ~ 5
六个元素时,如果想得到长度为 5 和 4 的子数组的和,只需分别减去第 0
和第 0 ~ 1
个元素即可。而由于是在 mid
两侧判断是否存在子数组满足条件,故直接比较子数组的最大和与最小的前缀和的大小既可。
参考视频:【LeetCode 刷题讲解】644. Maximum Average Subarray II
1 | public class Solution { |