269. Alien Dictionary

269. Alien Dictionary

TODO

class Solution:
    def alienOrder(self, words: List[str]) -> str:

        # Step 0: create data structures + the in_degree of each unique letter to 0.
        adj_list = defaultdict(set)
        in_degree = Counter({c : 0 for word in words for c in word})

        # Step 1: We need to populate adj_list and in_degree.
        # For each pair of adjacent words...
        for i in range(1, len(words)):
            first_word = words[i-1]
            second_word = words[i]
            i = 0
            j = 0
            while i < len(first_word) and j < len(second_word):
                c1 = first_word[i]
                c2 = second_word[j]
                # 找到第一個不一樣的字元,其中 c2 一定是在 c1 後面
                if c1 != c2:
                    if c2 not in adj_list[c1]:
                        adj_list[c1].add(c2)
                        in_degree[c2] += 1
                    break
                i += 1
                j += 1
            # Check that second word isn't a prefix of first word.    
            # 如果走完 while 迴圈,遇到這樣的例子如: abc, ab,這樣的情況是不合理的,
            if j == len(second_word) and i < len(first_word):
                return ""

        # Step 2: We need to repeatedly pick off nodes with an indegree of 0.
        output = []
        queue = deque([c for c in in_degree if in_degree[c] == 0])
        while queue:
            c = queue.popleft()
            output.append(c)
            for d in adj_list[c]:
                in_degree[d] -= 1
                if in_degree[d] == 0:
                    queue.append(d)

        # If not all letters are in output, that means there was a cycle and so
        # no valid ordering. Return "" as per the problem description.
        if len(output) < len(in_degree):
            return ""
        # Otherwise, convert the ordering we found into a string and return it.
        return "".join(output)