Longest Word in Dictionary

MediumTrie · Hash Set · Sorting🧩 TrieLeetCode #720 ↗Updated

Problem

You are given an array words of lowercase strings. A word is buildable if you can grow it one letter at a time from the right, and every intermediate prefix (lengths 1, 2, …) is also in words. Return the longest buildable word; break ties by the lexicographically smallest one, and return "" if no word qualifies.
Inputwords = ["w","wo","wor","worl","world"]Output"world"
Inputwords = ["a","banana","app","appl","ap","apply","apple"]Output"apple" ("apply" ties on length but is larger)
Inputwords = ["xy","yz"]Output"" (no single letters)

1 ≤ words.length ≤ 1000  ·  1 ≤ words[i].length ≤ 30  ·  lowercase English letters only

Try it yourself

Java
class Solution {
    public String longestWord(String[] words) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
Put the words in a trie and mark word ends. A word is buildable exactly when every node on its path is a word end, so a DFS that only steps into marked children visits precisely the buildable words.
PatternTrie

Instinct Many words, shared prefixes, and questions like "starts with", autocomplete, wildcard match or "search a board for all these words" - build a prefix tree.

Memory hack Words share their beginnings, so store each beginning once - walk one letter per step, and an end flag marks where a real word stops.

Open the Trie guide →

Approaches

Brute ForceCheck Every Prefix by Scanning the List

Time O(n2 · L2)Space O(1)

For each word, test each of its proper prefixes by scanning the whole array for an equal string. Keep the best candidate by (length desc, text asc). Direct translation of the definition, nothing clever.

Java
public String longestWord(String[] words) {
    String best = "";
    for (String w : words) {
        boolean ok = true;
        for (int len = 1; len < w.length() && ok; len++) {
            ok = contains(words, w.substring(0, len));
        }
        if (ok && (w.length() > best.length()
                || (w.length() == best.length() && w.compareTo(best) < 0))) {
            best = w;
        }
    }
    return best;
}

private boolean contains(String[] words, String target) {
    for (String s : words) {
        if (s.equals(target)) return true;
    }
    return false;
}

Correct but quadratic in the number of words — too slow beyond toy input.

At a glance

LevelApproachTimeSpace
Brute ForceCheck Every Prefix by Scanning the ListO(n2 · L2)O(1)
BetterSort, then Grow a Set of Buildable WordsO(n log n · L)O(n · L)
OptimalTrie + DFS Through Word-End NodesO(n · L)O(n · L)
Common pitfalls
  • Forgetting that every prefix must exist — checking only the len-1 prefix without sorting.
  • Wrong tie-break: return the smallest word among the longest, not the first one seen.
  • In the trie DFS, stepping into a child that is not a word end breaks the chain.
Interview tips
  • Restate “buildable” as “all prefixes present” before coding.
  • Mention the sort+set idea first; it's short and convincing, then offer the trie.
  • Explain why a–z DFS order plus a strict > handles ties for free.
Pattern
Trie with end markers → questions about words whose every prefix must also be a word.
My notes saved in this browser