-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathmaximum-average-subarray-ii.py
77 lines (54 loc) · 2.21 KB
/
maximum-average-subarray-ii.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
from typing import List
class Solution:
def findMaxAverage(self, nums: List[int], k: int) -> float:
def greater_exists(avg: float) -> bool:
prefix_sum = [0.0]
for num in nums:
prefix_sum.append(prefix_sum[-1] + float(num) - avg)
min_prev = float("+inf")
for pos in range(k, len(prefix_sum)):
min_prev = min(min_prev, prefix_sum[pos - k])
if prefix_sum[pos] - min_prev > 0:
return True
return False
precision = 1 / 100000
left, right = float(min(nums)), float(max(nums))
while (right - left) > precision:
middle = left + (right - left) / 2
if greater_exists(middle):
left = middle
else:
right = middle
return left
def findMaxAverageBruteForce2(self, nums: List[int], k: int) -> float:
partial_sums: List[int] = [0]
for num in nums:
partial_sums.append(partial_sums[-1] + num)
stack: List[int] = []
max_avg = float("-inf")
for pos in range(len(partial_sums)):
while stack and partial_sums[stack[-1]] > partial_sums[pos]:
first = stack.pop()
last = pos
if last - first >= k:
avg = (partial_sums[last] - partial_sums[first]) / (last - first)
max_avg = max(max_avg, avg)
for first in stack:
last = pos
if last - first >= k:
avg = (partial_sums[last] - partial_sums[first]) / (last - first)
max_avg = max(max_avg, avg)
stack.append(pos)
return max_avg
def findMaxAverageBruteForce(self, nums: List[int], k: int) -> float:
# Just an idea, haven't tested it
max_avg = 0.0
for left in range(len(nums)):
avg = 0.0
for right in range(left, len(nums)):
avg = avg * (right - left) / (right - left + 1) + nums[right] / (
right - left + 1
)
if right - left > k:
max_avg = max(max_avg, avg)
return max_avg