Skip to content

Commit 85d2095

Browse files
committed
Create alien-dictionary.py
1 parent dea10d2 commit 85d2095

1 file changed

Lines changed: 53 additions & 0 deletions

File tree

Python/alien-dictionary.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Time: O(|V|+|E|) = O(26 + 26^2) = O(1)
2+
# Space: O(|E|) = O(26^2) = O(1)
3+
4+
class Solution(object):
5+
def alienOrder(self, words):
6+
"""
7+
:type words: List[str]
8+
:rtype: str
9+
"""
10+
# Find ancestors of each node by DFS
11+
nodes, ancestors = {}, {}
12+
for i in xrange(len(words)):
13+
for c in words[i]:
14+
nodes[c] = True
15+
16+
for node in nodes.keys():
17+
ancestors[node] = []
18+
19+
for i in xrange(1, len(words)):
20+
self.findEdges(words[i - 1], words[i], ancestors)
21+
22+
# Output topological order by DFS
23+
result = []
24+
visited = {}
25+
for node in nodes.keys():
26+
if self.topSortDFS(node, node, ancestors, visited, result):
27+
return ""
28+
29+
return "".join(result)
30+
31+
32+
# Construct the graph.
33+
def findEdges(self, word1, word2, ancestors):
34+
str_len = min(len(word1), len(word2))
35+
for i in xrange(str_len):
36+
if word1[i] != word2[i]:
37+
ancestors[word2[i]].append(word1[i])
38+
break
39+
40+
41+
# Topological sort, return whether there is a cycle.
42+
def topSortDFS(self, root, node, ancestors, visited, result):
43+
if node not in visited:
44+
visited[node] = root
45+
for ancestor in ancestors[node]:
46+
if self.topSortDFS(root, ancestor, ancestors, visited, result):
47+
return True
48+
result.append(node)
49+
elif visited[node] == root:
50+
# Visited from the same root in the DFS path.
51+
# So it is cyclic.
52+
return True
53+
return False

0 commit comments

Comments
 (0)