-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlongest_balanced_sub_array.py
More file actions
63 lines (57 loc) · 2.02 KB
/
longest_balanced_sub_array.py
File metadata and controls
63 lines (57 loc) · 2.02 KB
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
class Solution(object):
def longestBalanced(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
n = len(nums)
tree_min = [0] * (4 * n)
tree_max = [0] * (4 * n)
lazy = [0] * (4 * n)
def push(v):
if lazy[v] != 0:
lazy[2*v] += lazy[v]
tree_min[2*v] += lazy[v]
tree_max[2*v] += lazy[v]
lazy[2*v+1] += lazy[v]
tree_min[2*v+1] += lazy[v]
tree_max[2*v+1] += lazy[v]
lazy[v] = 0
def update(v, tl, tr, l, r, add):
if l > r:
return
if l == tl and r == tr:
tree_min[v] += add
tree_max[v] += add
lazy[v] += add
else:
push(v)
tm = (tl + tr) // 2
update(2*v, tl, tm, l, min(r, tm), add)
update(2*v+1, tm+1, tr, max(l, tm+1), r, add)
tree_min[v] = min(tree_min[2*v], tree_min[2*v+1])
tree_max[v] = max(tree_max[2*v], tree_max[2*v+1])
def find_first_zero(v, tl, tr, limit):
if tl > limit:
return -1
if tree_min[v] > 0 or tree_max[v] < 0:
return -1
if tl == tr:
return tl if tree_min[v] == 0 else -1
push(v)
tm = (tl + tr) // 2
res = find_first_zero(2*v, tl, tm, limit)
if res != -1:
return res
return find_first_zero(2*v+1, tm+1, tr, limit)
last_pos = {}
max_len = 0
for i, x in enumerate(nums):
val = 1 if x % 2 == 0 else -1
prev = last_pos.get(x, -1)
last_pos[x] = i
update(1, 0, n-1, prev + 1, i, val)
left_idx = find_first_zero(1, 0, n-1, i)
if left_idx != -1:
max_len = max(max_len, i - left_idx + 1)
return max_len