forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
amount-of-time-for-binary-tree-to-be-infected.py
123 lines (112 loc) · 3.6 KB
/
amount-of-time-for-binary-tree-to-be-infected.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# Time: O(n)
# Space: O(h)
# Definition for a binary tree node.
class TreeNode(object):
def __init__(self, val=0, left=None, right=None):
pass
# iterative dfs, tree dp
class Solution(object):
def amountOfTime(self, root, start):
"""
:type root: Optional[TreeNode]
:type start: int
:rtype: int
"""
def iter_dfs(root, start):
result = -1
stk = [(1, (root, [-1]*2))]
while stk:
step, args = stk.pop()
if step == 1:
curr, ret = args
if curr is None:
continue
left, right = [-1]*2, [-1]*2
stk.append((2, (curr, left, right, ret)))
stk.append((1, (curr.right, right)))
stk.append((1, (curr.left, left)))
elif step == 2:
curr, left, right, ret = args
d = -1
if curr.val == start:
d = 0
result = max(left[0], right[0])+1
elif left[1] >= 0:
d = left[1]+1
result = max(result, right[0]+1+d)
elif right[1] >= 0:
d = right[1]+1
result = max(result, left[0]+1+d)
ret[:] = [max(left[0], right[0])+1, d] # [height, dist_to_start]
return result
return iter_dfs(root, start)
# Time: O(n)
# Space: O(h)
# dfs, tree dp
class Solution2(object):
def amountOfTime(self, root, start):
"""
:type root: Optional[TreeNode]
:type start: int
:rtype: int
"""
def dfs(curr, start, result):
if curr is None:
return [-1, -1]
left = dfs(curr.left, start, result)
right = dfs(curr.right, start, result)
d = -1
if curr.val == start:
d = 0
result[0] = max(left[0], right[0])+1
elif left[1] >= 0:
d = left[1]+1
result[0] = max(result[0], right[0]+1+d)
elif right[1] >= 0:
d = right[1]+1
result[0] = max(result[0], left[0]+1+d)
return [max(left[0], right[0])+1, d] # [height, dist_to_start]
result = [-1]
dfs(root, start, result)
return result[0]
# Time: O(n)
# Space: O(n)
# bfs
class Solution3(object):
def amountOfTime(self, root, start):
"""
:type root: Optional[TreeNode]
:type start: int
:rtype: int
"""
def bfs(root):
adj = collections.defaultdict(list)
q = [root]
while q:
new_q = []
for u in q:
for v in (u.left, u.right):
if v is None:
continue
adj[u.val].append(v.val)
adj[v.val].append(u.val)
new_q.append(v)
q = new_q
return adj
def bfs2(adj, start):
result = -1
q = [start]
lookup = {start}
while q:
new_q = []
for u in q:
for v in adj[u]:
if v in lookup:
continue
lookup.add(v)
new_q.append(v)
q = new_q
result += 1
return result
adj = bfs(root)
return bfs2(adj, start)