forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathminimum-time-to-collect-all-apples-in-a-tree.py
130 lines (117 loc) · 3.75 KB
/
minimum-time-to-collect-all-apples-in-a-tree.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
124
125
126
127
128
129
130
# Time: O(n)
# Space: O(n)
import collections
class Solution(object):
def minTime(self, n, edges, hasApple):
"""
:type n: int
:type edges: List[List[int]]
:type hasApple: List[bool]
:rtype: int
"""
graph = collections.defaultdict(list)
for u, v in edges:
graph[u].append(v)
graph[v].append(u)
result = [0, 0]
s = [(1, (-1, 0, result))]
while s:
step, params = s.pop()
if step == 1:
par, node, ret = params
ret[:] = [0, int(hasApple[node])]
for nei in reversed(graph[node]):
if nei == par:
continue
new_ret = [0, 0]
s.append((2, (new_ret, ret)))
s.append((1, (node, nei, new_ret)))
else:
new_ret, ret = params
ret[0] += new_ret[0]+new_ret[1]
ret[1] |= bool(new_ret[0]+new_ret[1])
return 2*result[0]
# Time: O(n)
# Space: O(n)
class Solution_Recu(object):
def minTime(self, n, edges, hasApple):
"""
:type n: int
:type edges: List[List[int]]
:type hasApple: List[bool]
:rtype: int
"""
def dfs(graph, par, node, hasApple):
result, extra = 0, int(hasApple[node])
for nei in graph[node]:
if nei == par:
continue
count, found = dfs(graph, node, nei, hasApple)
result += count+found
extra |= bool(count+found)
return result, extra
graph = collections.defaultdict(list)
for u, v in edges:
graph[u].append(v)
graph[v].append(u)
return 2*dfs(graph, -1, 0, hasApple)[0]
# Time: O(n)
# Space: O(n)
class Solution2(object):
def minTime(self, n, edges, hasApple):
"""
:type n: int
:type edges: List[List[int]]
:type hasApple: List[bool]
:rtype: int
"""
graph = collections.defaultdict(list)
for u, v in edges:
graph[u].append(v)
graph[v].append(u)
result = [0]
s = [(1, (-1, 0, result))]
while s:
step, params = s.pop()
if step == 1:
par, node, ret = params
tmp = [int(hasApple[node])]
s.append((3, (tmp, ret)))
for nei in reversed(graph[node]):
if nei == par:
continue
new_ret = [0]
s.append((2, (new_ret, tmp, ret)))
s.append((1, (node, nei, new_ret)))
elif step == 2:
new_ret, tmp, ret = params
ret[0] += new_ret[0]
tmp[0] |= bool(new_ret[0])
else:
tmp, ret = params
ret[0] += tmp[0]
return 2*max(result[0]-1, 0)
# Time: O(n)
# Space: O(n)
class Solution2_Recu(object):
def minTime(self, n, edges, hasApple):
"""
:type n: int
:type edges: List[List[int]]
:type hasApple: List[bool]
:rtype: int
"""
def dfs(graph, par, node, has_subtree):
result, extra = 0, int(hasApple[node])
for nei in graph[node]:
if nei == par:
continue
count = dfs(graph, node, nei, hasApple)
result += count
extra |= bool(count)
return result+extra
graph = collections.defaultdict(list)
for u, v in edges:
graph[u].append(v)
graph[v].append(u)
return 2*max(dfs(graph, -1, 0, hasApple)-1, 0)