forked from shuboc/LeetCode-2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathalien-dictionary.py
53 lines (44 loc) · 1.6 KB
/
alien-dictionary.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
# Time: O(|V|+|E|) = O(26 + 26^2) = O(1)
# Space: O(|E|) = O(26^2) = O(1)
class Solution(object):
def alienOrder(self, words):
"""
:type words: List[str]
:rtype: str
"""
# Find ancestors of each node by DFS
nodes, ancestors = {}, {}
for i in xrange(len(words)):
for c in words[i]:
nodes[c] = True
for node in nodes.keys():
ancestors[node] = []
for i in xrange(1, len(words)):
self.findEdges(words[i - 1], words[i], ancestors)
# Output topological order by DFS
result = []
visited = {}
for node in nodes.keys():
if self.topSortDFS(node, node, ancestors, visited, result):
return ""
return "".join(result)
# Construct the graph.
def findEdges(self, word1, word2, ancestors):
str_len = min(len(word1), len(word2))
for i in xrange(str_len):
if word1[i] != word2[i]:
ancestors[word2[i]].append(word1[i])
break
# Topological sort, return whether there is a cycle.
def topSortDFS(self, root, node, ancestors, visited, result):
if node not in visited:
visited[node] = root
for ancestor in ancestors[node]:
if self.topSortDFS(root, ancestor, ancestors, visited, result):
return True
result.append(node)
elif visited[node] == root:
# Visited from the same root in the DFS path.
# So it is cyclic.
return True
return False