Skip to content

Commit d81eecb

Browse files
committed
Runtime: 6663 ms (Top 46.4%) | Memory: 339.09 MB (Top 7.1%)
1 parent 43b5898 commit d81eecb

File tree

1 file changed

+43
-59
lines changed

1 file changed

+43
-59
lines changed
Lines changed: 43 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,47 @@
1-
class Trie:
2-
def __init__(self):
3-
self.root = {}
4-
5-
def add(self, word):
6-
cur = self.root
7-
for c in word:
8-
if c not in cur:
9-
cur[c] = {}
10-
cur = cur[c]
11-
12-
def find(self, word):
13-
cur = self.root
14-
res = ""
15-
for c in word:
16-
desired = "1" if c == "0" else "0"
17-
if not desired in cur:
18-
desired = c
19-
res += desired
20-
cur = cur[desired]
21-
return res
22-
23-
def delete(self, word):
24-
cur = self.root
25-
path = []
26-
for c in word:
27-
path.append(cur)
28-
cur = cur[c]
29-
for c, obj in zip(word[::-1], path[::-1]):
30-
if not obj[c]:
31-
del obj[c]
32-
else:
33-
break
34-
35-
1+
# Runtime: 6663 ms (Top 46.4%) | Memory: 339.09 MB (Top 7.1%)
2+
363
class Solution:
374
def maxGeneticDifference(self, parents: List[int], queries: List[List[int]]) -> List[int]:
38-
#since max(10^5,2*10^5) < 2^18, 18 bits are enough to represent a value or node as a bit string
39-
def makebin(x):
40-
return bin(x)[2:].zfill(18)
41-
node_queries = defaultdict(list)
42-
for i, (node, val) in enumerate(queries):
43-
node_queries[node].append((i,val))
44-
graph = defaultdict(list)
45-
for y, x in enumerate(parents):
46-
graph[x].append(y)
47-
res = [-1 for _ in queries]
48-
tree = Trie()
49-
#dfs traversal
50-
#during the traversal, it is making bit Trie using the nodes from the root to the current node of the graph
51-
def dfs(v):
52-
v_bin = makebin(v)
53-
tree.add(v_bin)
54-
for i, val in node_queries[v]:
55-
val_bin = makebin(val)
56-
target_bin = tree.find(val_bin)
57-
res[i] = int(target_bin,2)^val
58-
for w in graph[v]:
59-
dfs(w)
60-
tree.delete(v_bin)
61-
dfs(graph[-1][0]) #dfs from the root
5+
adj_map = collections.defaultdict(set)
6+
root = None
7+
for i, node in enumerate(parents):
8+
if node == -1:
9+
root = i
10+
else:
11+
adj_map[node].add(i)
12+
queries_map = collections.defaultdict(set)
13+
14+
for q in queries:
15+
queries_map[q[0]].add(q[1])
16+
self.res_map = {}
17+
def helperDFS(curr_root,prefix_map):
18+
19+
if curr_root in queries_map:
20+
for val in queries_map[curr_root]:
21+
bin_rep = format(val, '020b')
22+
best_bin = ""
23+
print(bin_rep)
24+
for i in range(20):
25+
if prefix_map[best_bin+str(1-int(bin_rep[i]))]:
26+
best_bin += str(1-int(bin_rep[i]))
27+
else:
28+
best_bin += bin_rep[i]
29+
self.res_map[(curr_root,val)] = int(best_bin,2) ^ val
30+
for child in adj_map[curr_root]:
31+
bin_rep = format(child, '020b')
32+
for i in range(1, len(bin_rep)+1):
33+
prefix_map[bin_rep[0:i]].add(child)
34+
helperDFS(child, prefix_map)
35+
for i in range(1, len(bin_rep)+1):
36+
prefix_map[bin_rep[0:i]].remove(child)
37+
38+
initial_prefixmap = collections.defaultdict(set)
39+
root_rep = format(root, '020b')
40+
for i in range(1,21):
41+
initial_prefixmap[root_rep[0:i]].add(root)
42+
helperDFS(root, initial_prefixmap)
43+
res = []
44+
for q in queries:
45+
res.append(self.res_map[(q[0],q[1])])
6246
return res
6347

0 commit comments

Comments
 (0)