2Brute2Best
🔥0

Alien Dictionary

Hard·GeeksforGeeksBasic Anchor
GeeksforGeeks
30-Second Mental ModelTopological Sort — Build the graph, then sort (Kahn's algorithm)
Complexity:O(U! · N · L)→O(N · L)
Key Insight

Compare each pair of neighbours and stop at its first differing letter. That one letter gives an arrow. Then run Kahn's algorithm on the arrows: place letters with no arrows pointing in, and remove their arrows as you go.

Core Validity Invariant

A letter can be placed next only when every arrow pointing into it has already been placed. Then no rule is broken, because nothing unplaced must come before it.

01

Problem

You get a list of words. The list is sorted by the dictionary order of an alien language. The alien alphabet uses lowercase letters, but you do not know how those letters are ordered.

Find a letter order that makes the list sorted. Return every letter that appears in the words, once each, in that order, as one string.

More than one order can work. Any valid one is accepted. If no order can make the list sorted, return an empty string.

Input

words: a list of strings, given in the alien dictionary order.

Output

One string with each letter that appears in words exactly once, in a valid alien order. Or an empty string if no order works.

Example 1
Input: words = ["baa", "abcd", "abca", "cab", "cad"]
Output: "bdac"

The neighbouring pairs say: b before a (baa vs abcd), d before a (abcd vs abca), a before c (abca vs cab), b before d (cab vs cad). "bdac" respects all four. Any other valid order is also accepted.

Example 2
Input: words = ["caa", "aaa", "aab"]
Output: "cab"

caa vs aaa says c comes before a. aaa vs aab says a comes before b. Only one order fits: c, a, b.

Example 3
Input: words = ["ab", "ba", "ab"]
Output: ""

ab before ba says a comes before b. ba before ab says b comes before a. Those two rules clash, so no order works.

Constraints
  • • Every word uses only lowercase letters a to z.
  • • Some inputs have no valid order. For those, return an empty string.
02

First, think yourself

Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.

  1. 1.

    Each pair of neighbouring words tells me something about two letters. Which letters in the pair actually matter?

  2. 2.

    For the words cat and cap, do the letters after the first difference tell me anything? Why or why not?

  3. 3.

    If I draw every "x comes before y" fact as an arrow x → y, what kind of graph do I get, and what do I need to find in it?

  4. 4.

    Which letters can go first in the answer?

  5. 5.

    If a set of arrows forms a loop, what happens to the letters in that loop while I keep placing letters that have no arrows pointing in?

03

Brute force approach

05

Optimized approach

06

Why does this algorithm work?

07

Dry run

08

All approaches compared

ApproachIdeaTimeSpace
Brute ForceTry each order of the letters; keep the first one that sorts the listO(U! · N · L)O(U)
OptimalOne rule per neighbouring pair; then place letters that have nothing before themO(N · L)O(1)
09

Why does this belong to this pattern?

Clues in the problem statement
  • “words sorted in an alien language”The sorted list hides a set of letter comparisons. Build the graph from them, then sort it.
  • “return any valid order”This is a topological sort: any order that puts every arrow's tail before its head.
  • “empty string if no order”A cycle makes Kahn stop early, so the count of placed letters tells us.
neighbouring pairs+first differing letter = one rule+topological order of the letters→Topological Sort — Build the graph, then sort (Kahn's algorithm)

The graph is hidden: the words only say which letter comes first in each neighbouring pair. Each pair gives one rule, from its first differing letter. Letters after that point are never compared for a rule, so the first difference is all you read. The next question, Alien Dictionary, keeps this rule and adds the prefix case and the letters that have no rules.

10

Don't make this mistake

Reading past the first difference (string-diff habit)
✗ for (size_t j = 0; j < m; j++) if (a[j] != b[j]) addRule(a[j], b[j]); // keeps going
✓ for (size_t j = 0; j < m; j++) if (a[j] != b[j]) { addRule(a[j], b[j]); break; }

A string diff marks every mismatch, but a sorted list only decides the pair at its first mismatch. On ["ab", "ca", "cb"], the pair ab vs ca gives a → c at index 0. Reading on gives b vs a at index 1, a false arrow b → a. Together with a → b from ca vs cb, that is a cycle, so the code returns "". But "acb" is a valid answer.

Returning the partial order when a cycle stops Kahn
✗ return order;
✓ return (int)order.size() == total ? order : "";

On ["d", "ab", "ba", "ab"], the rules are d → a, a → b and b → a. Kahn places d, then a and b wait on each other. The queue is empty with 1 of 3 letters placed. Returning "d" is wrong: the answer must be empty.

Comparing the whole words instead of neighbours

Comparing every pair of words adds rules that the neighbouring pairs already imply, so the answer is still right but the work grows with N². Only neighbours are needed: a sorted list is sorted as soon as each neighbouring pair is in order.

11

Want to implement this?

Write it yourself on GeeksforGeeks, then come back and compare your code with the solutions above.

Open coding workspace
How did it go?
Beyond The LeetCode Problem

How this concept connects to System Design & C++ Systems

Bridge DSA with production engineering

Top engineering interviews test whether you understand how algorithms like Topological Sort translate into production architectures and low-level memory mechanics.