Leetcode: 269. Alien Dictionary
Understand the problem
Given a sequence of words sorted lexicographically using unknown alphabetic order, return the alphabet's letters sorted in respect to the alphabet's rule.
Devise a plan
Modeling as a graph problem, letters are vertices and an edge
Carry out the plan
class Solution: def alienOrder(self, words: List[str]) -> str: A = {c: [] for w in words for c in w} for a, b in zip(words, words[1:]): if a == b: continue if a.startswith(b): return "" i = 0 while i < len(a) and i < len(b) and a[i] == b[i]: i += 1 if i < len(a) and i < len(b): A[a[i]].append(b[i]) deg = {c: 0 for c in A} for u in A: for v in A[u]: deg[v] += 1 queue = [u for u in A if deg[u] == 0] ans = [] for u in queue: ans.append(u) for v in A[u]: deg[v] -= 1 if deg[v] == 0: queue.append(v) if len(ans) != len(A): return "" return "".join(ans)
from typing import List class Solution: def alienOrder(self, words: List[str]) -> str: adj = {} for w1, w2 in zip(words, words[1:]): if len(w2) < len(w1) and w1.startswith(w2): return "" for c1, c2 in zip(w1, w2): if c1 != c2: adj.setdefault(c1, set()) adj[c1].add(c2) break NOT_VISITED = "NOT_VISITED" OPEN = "OPEN" CLOSED = "CLOSED" status = {c: NOT_VISITED for w in words for c in w} ans = [] def dfs(u): if status[u] == CLOSED: return True if status[u] == OPEN: return False status[u] = OPEN for v in adj.get(u, []): if not dfs(v): return False ans.append(u) status[u] = CLOSED return True for c in status: if status[c] == NOT_VISITED: if not dfs(c): return "" return "".join(reversed(ans)) assert Solution().alienOrder(["wrt","wrf","er","ett","rftt"]) == "wertf" assert Solution().alienOrder(["z","x"]) == "zx" assert Solution().alienOrder(["z","x","z"]) == "" assert Solution().alienOrder(["z","z"]) == "z" assert Solution().alienOrder(["abc","ab"]) == ""