【Lintcode】python - [892] Alien Dictionary 個人解法筆記

題目出處

892 · Alien Dictionary

難度

Hard

個人範例程式碼

import heapq

from typing import (
    List,
)

class Solution:
    """
    @param words: a list of words
    @return: a string which is correct order
    """
    def alien_order(self, words: List[str]) -> str:
        # Write your code here
        graph = self.build_graph(words)
        if not graph:
            return ""

        return self.topological_sort(graph)

    def build_graph(self, words):
        graph = {} # node: neighbors

        # init graph
        for word in words:
            for c in word:
                if c not in graph:
                    graph[c] = set()

        # add edges
        n = len(words)
        for i in range(n-1): # compare i, i+1
            max_compare_length = min(len(words[i]), len(words[i+1]))
            for j in range(max_compare_length):
                if words[i][j] != words[i+1][j]: # compare two words, if different [i]->[i+1]
                    graph[words[i][j]].add(words[i+1][j])
                    break # finish add edge

                if j == max_compare_length - 1: # already last word, but edge not found
                    # case: err, errt (next must be longer)
                    if len(words[i]) > len(words[i+1]): 
                        return None # error case, early return 

        return graph

    def topological_sort(self, graph): 
        # init indegree, all node = 0
        indegree = {
            node: 0 for node in graph
        }

        # calculate indegree
        for node in graph:
            for neighbor in graph[node]:
                indegree[neighbor] = indegree[neighbor] + 1

        # find 0 indegree
        heap = [node for node in graph if indegree[node] == 0]
        heapq.heapify(heap) # smallest in lexicographical order`

        # bfs - topological sorting
        ans_order = ""
        while heap:
            node = heapq.heappop(heap)
            ans_order += node
            for neighbor in graph[node]:
                indegree[neighbor] -= 1
                if indegree[neighbor] == 0:
                    heapq.heappush(heap, neighbor)

        # if all nodes popped
        if len(ans_order) == len(graph):
            return ans_order

        return ""

最近在練習程式碼本身就可以自解釋的 Coding style,可以嘗試直接閱讀程式碼理解

算法說明

這題要同時考到建構出一個 graph,
並還需要做 topological sorting (BFS) 找出路徑。

(這題還沒有靠自己完全寫出來,目前先參考下方 reference 進行仿寫)

input handling

建構 graph 時,注意有沒有例外狀況

例如:沒有找到任何的不同,且 length word[i] > word[i+1]
(errt, err) 此類順序是有問題的

Boundary conditions

在 graph 與 bfs 中控制搜尋範圍,搜尋完全部 node 就正常結束。
(沒有全部搜尋完,就沒有結果)

Reference