|
| 1 | +# coding: utf-8 |
| 2 | + |
| 3 | +class Solution: |
| 4 | + # @param {int[]} nums an array with positive and negative numbers |
| 5 | + # @param {int} k an integer |
| 6 | + # @return {double} the maximum average |
| 7 | + def maxAverage(self, nums, k): |
| 8 | + # Write your code here |
| 9 | + self.min = sys.maxsize # 平均数的下限,不可能比最小的小。 |
| 10 | + self.max = -self.min # 平均数的上限,不可能比最大的大。 |
| 11 | + for i in nums: |
| 12 | + if i > self.max: |
| 13 | + self.max = i |
| 14 | + if i < self.min: |
| 15 | + self.min = i |
| 16 | + while (self.max - self.min) > 0.0001: |
| 17 | + mid = float(self.max + self.min) / 2 |
| 18 | + if self._search(nums, k, mid): # 调整平均值的上下限 |
| 19 | + self.min = mid |
| 20 | + else: |
| 21 | + self.max = mid |
| 22 | + return self.max |
| 23 | + |
| 24 | + def _search(self, nums, k, mid): |
| 25 | + bar = 0 |
| 26 | + sums = [0] * (len(nums) + 1) |
| 27 | + for i in range(1, len(sums)): |
| 28 | + # sums[i] = (nums[0] + ... + nums[i - 1]) - (mid * i) |
| 29 | + sums[i] = sums[i - 1] + nums[i - 1] - mid |
| 30 | + if i > k: |
| 31 | + ''' |
| 32 | + 这里首先看sums[i] < 0的情况(因为bar的初始值为0)。 |
| 33 | + - 如果sums[i]小于bar,第一次意味着前k个数的平均数都小于mid。 |
| 34 | + - 和sums[i - k + 1]比较有什么用?如果比bar小的话,说明在计算连续 |
| 35 | + k个子数组时可以把前面的结果扔掉,完全副作用啊。在程序里体现就 |
| 36 | + 是通过min函数调整bar。 |
| 37 | + 那么后面就容易理解了,如果大于bar,就说明有平均值大于mid。这里的 |
| 38 | + 精妙之处在于不去试图计算平均值,而是不断收敛平均值上下限的范围。 |
| 39 | + ''' |
| 40 | + if sums[i] >= bar: |
| 41 | + return True |
| 42 | + bar = min(bar, sums[i - k + 1]) |
| 43 | + return False |
| 44 | + |
| 45 | +# medium: http://lintcode.com/zh-cn/problem/maximum-average-subarray/ |
0 commit comments