Last Updated: April 4, 2026
We have a list of words and need to find the longest one that has a complete "chain" of prefixes in the dictionary. For a word like "world" to be valid, the dictionary must also contain "w", "wo", "wor", and "worl". Each prefix builds on the previous one by adding exactly one character at the end.
If two valid words have the same length, we pick the lexicographically smaller one. So between "apply" and "apple", we return "apple" because it comes first alphabetically.
The key observation is that this is fundamentally a prefix-chain problem. A word of length k is buildable only if its prefix of length k-1 is also buildable. Words of length 1 are always buildable (they are trivially built from the empty string by adding one character). This recursive structure suggests we can either use sorting with a hash set or a Trie data structure.
words.length <= 1000 → The total number of words is small. Even O(n^2) approaches are feasible here.words[i].length <= 30 → Individual words are short. Operations on a single word (like extracting prefixes) are cheap.The most direct approach is to take each word, extract every prefix of that word, and check if all those prefixes exist in the dictionary. If they do, the word is "buildable." We keep track of the longest buildable word seen so far, breaking ties by lexicographic order.
To make prefix lookups fast, we toss all words into a hash set first. Then for each word, we check each of its prefixes against the set.
a. Check if every prefix of this word (from length 1 up to length - 1) exists in the hash set
b. If all prefixes exist, compare this word against the current result: update if it is longer, or if it is the same length but lexicographically smaller
Input:
For the word "world", we check prefixes: "w" (in set), "wo" (in set), "wor" (in set), "worl" (in set). All present, so "world" is buildable.
Output:
The brute force checks every prefix redundantly. What if we processed words from shortest to longest, so we only need to check the immediate prefix?
If we sort the words first by length (shorter words first), then alphabetically within the same length, we can process words in order. By the time we encounter a word of length k, all words of length k-1 have already been processed.
A word is buildable if its prefix of length k-1 (the word minus its last character) is already in our set of buildable words. Words of length 1 are always buildable since they are built from the empty string by adding one character.
By sorting words from shortest to longest and alphabetically within the same length, we guarantee two things. First, when we check a word, its one-character-shorter prefix has already been considered. If that prefix was buildable, it is already in our set. Second, for words of the same length, the lexicographically smallest one comes first. So the first buildable word we find at any given length is automatically the best one at that length.
The beauty of only checking the immediate prefix is that buildability is transitive. If "app" is in the buildable set, it means "ap" was buildable, which means "a" was buildable. We do not need to re-verify the entire chain every time.
a. Check if the prefix of length (word.length - 1) is in the buildable set
b. If yes, add this word to the buildable set
c. Update the result if this word is longer than the current result
The sorting approach is clean, but a Trie naturally represents shared prefixes without substring creation. Can we walk the Trie directly?
A Trie (prefix tree) is a natural fit here because the problem is fundamentally about prefixes. We insert all words into a Trie, marking which nodes represent the end of a word. Then we search for the longest path from the root where every node along the way is a complete word.
Each node in the Trie represents a prefix. If that prefix is itself a word in the dictionary (its isEnd flag is true), then we can "build" up to that point. We want the deepest node reachable by following only edges where each intermediate node is a complete word. A DFS starting from the root, exploring children alphabetically and only visiting end-of-word nodes, does exactly this.