269. 火星词典
原题链接
现有一种使用字母的全新语言,这门语言的字母顺序与英语顺序不同。
假设,您并不知道其中字母之间的先后顺序。但是,会收到词典中获得一个 不为空的 单词列表。因为是从词典中获得的,所以该单词列表内的单词已经 按这门新语言的字母顺序进行了排序。
您需要根据这个输入的列表,还原出此语言中已知的字母顺序。
示例 1:
输入:
[
“wrt”,
“wrf”,
“er”,
“ett”,
“rftt”
]
输出: “wertf”
示例 2:
输入:
[
“z”,
“x”
]
输出: “zx”
示例 3:
输入:
[
“z”,
“x”,
“z”
]
输出: “”
解释: 此顺序是非法的,因此返回 “”。
注意:
你可以默认输入的全部都是小写字母
假如,a 的字母排列顺序优先于 b,那么在给定的词典当中 a 定先出现在 b 前面
若给定的顺序是不合法的,则返回空字符串即可
若存在多种可能的合法字母顺序,请返回其中任意一种顺序即可
# 火星字典
class Solution:
def alienOrder(self,words):
dic = self.build_dict(words)
graph = self.build_adj(words,dic)
path = []
visited = [0 for _ in range(len(dic))]
for i in range(len(dic)):
if not visited[j]:
state = self.dfs(i,graph,path,visited)
if not state:
return ""
path.reverse()
temp = {dic[k]:k for k in dic}
ans = "".join([temp[i] for i in path])
return ans
def dfs(self,start,adj,path,visited):
visited[start] = 1
for next_node in adj[start]:
if visited[next_node] == 1:
return False
if visited[next_node] == 2:
continue
state = self.dfs(next_node,adj,path,visited)
if not state:
return False
visited[start] = 2
path.append(start)
return True
def build_dict(self,words):
dic = {}
index = 0
for word in words:
for char in word:
if char not in dic:
dic[char] = index
index += 1
return dic
def build_adj(self,words,dic):
graph = {}
for i in range(len(dic)):
graph[i] = []
for index,word in enumerate(words):
if index<len(words)-1:
i = 0
while i<len(words[index]) and i <len(words[index+1]) and words[index][i] == words[index+1][i]:
i += 1
if i < len(words[index]) and i < len(words[index+1]):
graph[dic[words[index][i]]].append(dic[words[index+1][i]])
return graph