forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
find-maximum-non-decreasing-array-length.py
98 lines (85 loc) · 2.67 KB
/
find-maximum-non-decreasing-array-length.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# Time: O(n)
# Space: O(n)
# dp, greedy, prefix sum, mono stack, two pointers
class Solution(object):
def findMaximumLength(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
dp = prefix = left = 0
stk = [(0, 0, 0)]
for right in xrange(len(nums)):
prefix += nums[right]
while left+1 < len(stk) and stk[left+1][0] <= prefix:
left += 1
last, dp = prefix-stk[left][1], stk[left][2]+1
while stk and stk[-1][0] >= last+prefix:
stk.pop()
stk.append((last+prefix, prefix, dp))
left = min(left, len(stk)-1)
return dp
# Time: O(n)
# Space: O(n)
import collections
# greedy, prefix sum, mono deque
class Solution2(object):
def findMaximumLength(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
dp = prefix = prev_prefix = prev_dp = 0
dq = collections.deque()
for right in xrange(len(nums)):
prefix += nums[right]
while dq and dq[0][0] <= prefix:
_, prev_prefix, prev_dp = dq.popleft()
last, dp = prefix-prev_prefix, prev_dp+1
while dq and dq[-1][0] >= last+prefix:
dq.pop()
dq.append((last+prefix, prefix, dp))
return dp
# Time: O(nlogn)
# Space: O(n)
import bisect
# dp, greedy, prefix sum, mono stack, binary search
class Solution3(object):
def findMaximumLength(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
dp = prefix = left = 0
stk = [(0, 0, 0)]
for right in xrange(len(nums)):
prefix += nums[right]
left = bisect.bisect_left(stk, (prefix+1, 0, 0))-1
last, dp = prefix-stk[left][1], stk[left][2]+1
while stk and stk[-1][0] >= last+prefix:
stk.pop()
stk.append((last+prefix, prefix, dp))
return dp
# Time: O(nlogn)
# Space: O(n)
import bisect
# dp, greedy, prefix sum, binary search
class Solution4(object):
def findMaximumLength(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
prefix = [0]*(len(nums)+1)
for i in xrange(len(nums)):
prefix[i+1] = prefix[i]+nums[i]
dp = [float("inf")]*(len(nums)+1)
dp[0] = 0
prev = [-1]*(len(nums)+1)
left = -1
for right in xrange(len(nums)):
left = max(left, prev[right])
dp[right+1] = dp[left+1]+1
next_right = bisect.bisect_left(prefix, prefix[right+1]+(prefix[right+1]-prefix[left+1]))-1
prev[next_right] = right
return dp[-1]