Talentd
FleetCode
Make and follow sheets.Sign in

Alien Dictionary solution and explanation

HardArrayBreadth-First SearchDepth-First SearchGraph4 min read37.1% acceptanceUpdated 23 Mar 2026Premium elsewhere, free here
G-26. Alien Dictionary - Topological Sorttake U forward · 20:54 · 355K viewsWatch on YouTube
9 more videos on this problem
  1. G-26. Alien Dictionary - Topological Sorttake U forward · 20:54 · 355K views
  2. Alien Dictionary - Topological Sort - Leetcode 269 - PythonNeetCode · 22:05 · 238K views
  3. LeetCode 269. Alien Dictionary Explanation and Solutionhappygirlzt · 14:49 · 27K views
  4. ALIEN DICTIONARY | LEETCODE 269 | PYTHON TOPOLOGICAL SORT DFS SOLUTIONCracking FAANG · 23:41 · 5K views
  5. Leetcode 269 - Alien Dictionary (JAVA Solution Explained!)LC Bear · 31:24 · 3K views
  6. LeetCode 269. Alien DictionaryHappy Coding · 19:22 · 1K views
  7. Alien Dictionary | LeetCode 269 (Hard)Destination FAANG · 43:24 · 1K views
  8. Alien Dictionary | Leetcode 269. Alien Dictionary | Topological sorting | #FAANGcode Tree · 23:38 · 935 views
  9. LeetCode 269. Alien Dictionary (Kahn/BFS - Java)Kacy Codes · 18:58 · 478 views
  10. 269. Alien Dictionary | English | HardSimple Code - 단순코드 · 14:00 · 206 views

The problem

There is a new alien language that uses the English alphabet. However, the order of the letters is unknown to you.

You are given a list of strings words from the alien language's dictionary. Now it is claimed that the strings in words are sorted lexicographically by the rules of this new language.

If this claim is incorrect, and the given arrangement of string in words cannot correspond to any order of letters, return "".

Otherwise, return a string of the unique letters in the new alien language sorted in lexicographically increasing order by the new language's rules. If there are multiple solutions, return any of them.

Example 1:

Input: words = ["wrt","wrf","er","ett","rftt"]
Output: "wertf"

Example 2:

Input: words = ["z","x"]
Output: "zx"

Example 3:

Input: words = ["z","x","z"]
Output: ""
Explanation: The order is invalid, so return "".

Constraints:

  • 1 <= words.length <= 100
  • 1 <= words[i].length <= 100
  • words[i] consists of only lowercase English letters.

Approach overview

Problem Overview: You’re given a list of words already sorted according to an unknown alien language. Your task is to reconstruct the ordering of characters in that language. If the ordering is invalid (for example, a prefix rule violation), return an empty string.

Approach 1: Graph Construction + Kahn's Algorithm (BFS Topological Sort) (Time: O(V + E), Space: O(V + E))

Model the problem as a directed graph where each character is a node. Compare adjacent words in the sorted list and find the first position where they differ. That difference reveals the ordering rule: char1 -> char2. Build an adjacency list and track indegrees for each character. Then run a Breadth-First Search using Kahn’s algorithm: push all characters with indegree 0 into a queue and process them while decreasing neighbors' indegrees. The result forms the alien character order. If you process fewer nodes than exist, a cycle exists and the ordering is invalid.

This approach is preferred because BFS naturally produces a valid topological ordering while detecting cycles through leftover nodes. It also cleanly handles disconnected components in the graph.

Approach 2: Graph Construction + DFS Topological Sort (Time: O(V + E), Space: O(V + E))

The graph construction step is identical: compare adjacent words and add a directed edge for the first mismatching characters. Instead of using a queue, run a Depth-First Search to produce a topological ordering. Track node states (unvisited, visiting, visited). If DFS reaches a node marked as visiting, a cycle exists and the dictionary is invalid. After exploring all neighbors, push the node into a result stack. Reverse the stack to get the final character order.

This method is common in classic topological sort implementations. It’s slightly more compact but requires careful cycle detection with recursion state tracking.

Key Edge Case: Invalid Prefix

If a longer word appears before its prefix (for example "abc" before "ab"), the ordering is impossible. Detect this while comparing adjacent words. If the first word starts with the second but is longer, return an empty string immediately.

Recommended for interviews: Build the character graph and run BFS with Kahn’s algorithm. Interviewers expect you to recognize the hidden topological sorting problem. Showing how to extract ordering constraints from adjacent words demonstrates strong graph modeling skills, while the BFS solution shows you understand cycle detection and dependency ordering.

Solution

class Solution:
    def alienOrder(self, words: List[str]) -> str:
        g = [[False] * 26 for _ in range(26)]
        s = [False] * 26
        cnt = 0
        n = len(words)
        for i in range(n - 1):
            for c in words[i]:
                if cnt == 26:
                    break
                o = ord(c) - ord('a')
                if not s[o]:
                    cnt += 1
                    s[o] = True
            m = len(words[i])
            for j in range(m):
                if j >= len(words[i + 1]):
                    return ''
                c1, c2 = words[i][j], words[i + 1][j]
                if c1 == c2:
                    continue
                o1, o2 = ord(c1) - ord('a'), ord(c2) - ord('a')
                if g[o2][o1]:
                    return ''
                g[o1][o2] = True
                break
        for c in words[n - 1]:
            if cnt == 26:
                break
            o = ord(c) - ord('a')
            if not s[o]:
                cnt += 1
                s[o] = True

        indegree = [0] * 26
        for i in range(26):
            for j in range(26):
                if i != j and s[i] and s[j] and g[i][j]:
                    indegree[j] += 1
        q = deque()
        ans = []
        for i in range(26):
            if s[i] and indegree[i] == 0:
                q.append(i)
        while q:
            t = q.popleft()
            ans.append(chr(t + ord('a')))
            for i in range(26):
                if s[i] and i != t and g[t][i]:
                    indegree[i] -= 1
                    if indegree[i] == 0:
                        q.append(i)
        return '' if len(ans) < cnt else ''.join(ans)
class Solution {

    public String alienOrder(String[] words) {
        boolean[][] g = new boolean[26][26];
        boolean[] s = new boolean[26];
        int cnt = 0;
        int n = words.length;
        for (int i = 0; i < n - 1; ++i) {
            for (char c : words[i].toCharArray()) {
                if (cnt == 26) {
                    break;
                }
                c -= 'a';
                if (!s[c]) {
                    ++cnt;
                    s[c] = true;
                }
            }
            int m = words[i].length();
            for (int j = 0; j < m; ++j) {
                if (j >= words[i + 1].length()) {
                    return "";
                }
                char c1 = words[i].charAt(j), c2 = words[i + 1].charAt(j);
                if (c1 == c2) {
                    continue;
                }
                if (g[c2 - 'a'][c1 - 'a']) {
                    return "";
                }
                g[c1 - 'a'][c2 - 'a'] = true;
                break;
            }
        }
        for (char c : words[n - 1].toCharArray()) {
            if (cnt == 26) {
                break;
            }
            c -= 'a';
            if (!s[c]) {
                ++cnt;
                s[c] = true;
            }
        }

        int[] indegree = new int[26];
        for (int i = 0; i < 26; ++i) {
            for (int j = 0; j < 26; ++j) {
                if (i != j && s[i] && s[j] && g[i][j]) {
                    ++indegree[j];
                }
            }
        }
        Deque<Integer> q = new LinkedList<>();
        for (int i = 0; i < 26; ++i) {
            if (s[i] && indegree[i] == 0) {
                q.offerLast(i);
            }
        }
        StringBuilder ans = new StringBuilder();
        while (!q.isEmpty()) {
            int t = q.pollFirst();
            ans.append((char) (t + 'a'));
            for (int i = 0; i < 26; ++i) {
                if (i != t && s[i] && g[t][i]) {
                    if (--indegree[i] == 0) {
                        q.offerLast(i);
                    }
                }
            }
        }
        return ans.length() < cnt ? "" : ans.toString();
    }
}
class Solution {
public:
    string alienOrder(vector<string>& words) {
        vector<vector<bool>> g(26, vector<bool>(26));
        vector<bool> s(26);
        int cnt = 0;
        int n = words.size();
        for (int i = 0; i < n - 1; ++i) {
            for (char c : words[i]) {
                if (cnt == 26) break;
                c -= 'a';
                if (!s[c]) {
                    ++cnt;
                    s[c] = true;
                }
            }
            int m = words[i].size();
            for (int j = 0; j < m; ++j) {
                if (j >= words[i + 1].size()) return "";
                char c1 = words[i][j], c2 = words[i + 1][j];
                if (c1 == c2) continue;
                if (g[c2 - 'a'][c1 - 'a']) return "";
                g[c1 - 'a'][c2 - 'a'] = true;
                break;
            }
        }
        for (char c : words[n - 1]) {
            if (cnt == 26) break;
            c -= 'a';
            if (!s[c]) {
                ++cnt;
                s[c] = true;
            }
        }
        vector<int> indegree(26);
        for (int i = 0; i < 26; ++i)
            for (int j = 0; j < 26; ++j)
                if (i != j && s[i] && s[j] && g[i][j])
                    ++indegree[j];
        queue<int> q;
        for (int i = 0; i < 26; ++i)
            if (s[i] && indegree[i] == 0)
                q.push(i);
        string ans = "";
        while (!q.empty()) {
            int t = q.front();
            ans += (t + 'a');
            q.pop();
            for (int i = 0; i < 26; ++i)
                if (i != t && s[i] && g[t][i])
                    if (--indegree[i] == 0)
                        q.push(i);
        }
        return ans.size() < cnt ? "" : ans;
    }
};
func alienOrder(words []string) string {
	g := [26][26]bool{}
	s := [26]bool{}
	cnt := 0
	n := len(words)
	for i := 0; i < n-1; i++ {
		for _, c := range words[i] {
			if cnt == 26 {
				break
			}
			c -= 'a'
			if !s[c] {
				cnt++
				s[c] = true
			}
		}
		m := len(words[i])
		for j := 0; j < m; j++ {
			if j >= len(words[i+1]) {
				return ""
			}
			c1, c2 := words[i][j]-'a', words[i+1][j]-'a'
			if c1 == c2 {
				continue
			}
			if g[c2][c1] {
				return ""
			}
			g[c1][c2] = true
			break
		}
	}
	for _, c := range words[n-1] {
		if cnt == 26 {
			break
		}
		c -= 'a'
		if !s[c] {
			cnt++
			s[c] = true
		}
	}

	inDegree := [26]int{}
	for _, out := range g {
		for i, v := range out {
			if v {
				inDegree[i]++
			}
		}
	}
	q := []int{}
	for i, in := range inDegree {
		if in == 0 && s[i] {
			q = append(q, i)
		}
	}
	ans := ""
	for len(q) > 0 {
		t := q[0]
		q = q[1:]
		ans += string(t + 'a')
		for i, v := range g[t] {
			if v {
				inDegree[i]--
				if inDegree[i] == 0 && s[i] {
					q = append(q, i)
				}
			}
		}
	}
	if len(ans) < cnt {
		return ""
	}
	return ans
}
Try this approach in the editor

Complexity analysis

ApproachTimeSpaceWhen to Use
Graph + BFS (Kahn's Algorithm)O(V + E)O(V + E)Preferred approach for interviews; naturally produces valid topological order and detects cycles
Graph + DFS Topological SortO(V + E)O(V + E)Good when implementing classic DFS-based topo sort with recursion and cycle detection
Naive Pairwise Character OrderingO(N * L)O(V)Useful for understanding how ordering constraints are extracted before building the graph

Frequently asked questions

Is Alien Dictionary easy or hard?

Alien Dictionary is considered a Hard problem because the challenge lies in modeling the graph correctly from word comparisons. After recognizing it as a topological sort problem, the algorithm itself is standard, but handling edge cases like prefix conflicts and cycles makes it tricky.

How to solve Alien Dictionary in O(n)?

Treat the problem as a topological sorting task. Compare adjacent words to build a directed graph of character dependencies, then run BFS (Kahn's algorithm) or DFS to generate the order. The complexity becomes O(V + E), which is linear relative to the number of characters and ordering constraints.

What is the best approach for Alien Dictionary?

The best approach models characters as nodes in a directed graph and extracts ordering constraints by comparing adjacent words. After building the graph, run a topological sort using Kahn’s algorithm (BFS) or DFS. Both run in O(V + E) time where V is the number of characters and E is the number of ordering relations.

What data structure is used in Alien Dictionary?

The main data structures are a graph (adjacency list) to store character dependencies, an indegree map to track prerequisites, and a queue or recursion stack for topological sorting. Hash maps and sets are commonly used to represent the graph efficiently.

What is the time complexity of Alien Dictionary?

The optimal solution runs in O(V + E) time and O(V + E) space. V represents the number of unique characters and E represents precedence rules derived from adjacent words. Graph construction and the topological sort each take linear time relative to nodes and edges.

Alien Dictionary Python or Java solution approach?

Python and Java solutions typically build an adjacency list using a dictionary or HashMap and track indegrees with another map or array. Then Kahn’s BFS algorithm processes nodes with indegree 0 using a queue. The same logic applies across Python, Java, C++, and Go implementations.

Is Alien Dictionary asked at Google, Amazon, or Meta?

Alien Dictionary frequently appears in interviews at companies like Google, Amazon, Meta, and Microsoft. The problem tests graph modeling, dependency resolution, and topological sorting—core concepts used in build systems and scheduling problems.

Comments

Now write it yourselfClose this page and solve Alien Dictionary in the editor, without looking.
Practise Alien Dictionary