-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlongest_nonnegative.py
More file actions
38 lines (33 loc) · 1016 Bytes
/
longest_nonnegative.py
File metadata and controls
38 lines (33 loc) · 1016 Bytes
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
"""Find the length of the longest contiguous subarray with a non-negative sum.
Uses prefix sums and two-pointer scanning over forward minima and reverse
maxima.
"""
def longest_non_negative(data):
neginf = sum(abs(e) for e in data) * -1000 # -infty
data = [neginf] + data + [neginf]
presum = [0]
for idx, val in enumerate(data):
presum.append(val + presum[idx])
max_rev = [0 for _ in presum]
max_rev[-1] = presum[-1]
for i in range(len(presum) - 2, -1, -1):
max_rev[i] = max(presum[i], max_rev[i + 1])
min_fwd = [0 for _ in presum]
for i in range(1, len(presum)):
min_fwd[i] = min(presum[i], min_fwd[i - 1])
lo = 0
hi = 0
mx = 0
while True:
lv = min_fwd[lo]
rv = max_rev[hi]
mx = max(mx, (hi - lo - 1))
if rv - lv >= 0:
hi += 1
if hi >= len(max_rev):
break
else:
lo += 1
if lo >= len(min_fwd):
break
return mx