269. Alien Dictionary

字典是以 lexicographically 排列的,那单个字母间的排序信息只能通过单词 one by one 的比较来获得,遍历比较后,可以知道字母之间 one to one 的前后关系。

把这种前后关系当作 node 之间的 bridge 来理解的话,就可以把所有字母理解为一个graph,那么想得到 overall 的字母顺序,对这个 graph 进行topological sort就可以。

topological sort 可以用 indegree Sort 或者 DFS 来做。

class Solution:
    def alienOrder(self, words: List[str]) -> str:
        edges = self.graphify(words)
        return self.topologicalSort(edges)
    
    
    def graphify(self, words):
        edges = {letter: set() for letter in words[0]}
        for i in range(1, len(words)):
            prev, curr = words[i-1], words[i]
            #print("search words: %s | %s" % (prev, curr))
            edge_found = False
            # 无效情况 e.g. ["abcd", "ab"]
            if prev.startswith(curr) and len(prev) > len(curr):
                return {}
            for j in range(len(curr)):
                # 发现新字母
                if curr[j] not in edges:
                    edges[curr[j]] = set()
                # 发现 edge
                if not edge_found and j < len(prev) and curr[j] != prev[j]:
                    # 如果是新 edge,就记录
                    if (curr[j] not in edges[prev[j]]):
                        #print("edge found: %s -> %s" % (prev[j], curr[j]))
                        edges[prev[j]].add(curr[j])
                    # 不管是新 edge 还是已经记录过的 edge,后面的字母相对顺序都没有意义了。
                    edge_found = True
        return edges
    
    
    def topologicalSort(self, edges):
        order, path, visited = [], [], []
        for w in edges:
            if self.dfs(w, edges, path, visited, order):
                return ""
        return "".join(reversed(order))
    
    
    def dfs(self, node, edges, path, visited, order):
        if node in path:  return True
        if node in visited:  return
        path.append(node)
        for child in edges[node]:
            if self.dfs(child, edges, path, visited, order):
                return True
        path.pop()
        visited.append(node)
        order.append(node)
        return False
        

Last updated

Was this helpful?