Word Ladder

Shortest transformation sequence from begin to end via single-letter edits — BFS over a word graph.

Hard
Time O(N * L^2) Space O(N * L)
LeetCode
6 min read
bfs graph strings

Problem#

Given beginWord, endWord, and a word list, return the length of the shortest sequence begin -> ... -> end where every adjacent pair differs by exactly one letter and every intermediate word is in the list. Return 0 if no such sequence exists.

Examples#

  • begin = "hit", end = "cog", words = ["hot","dot","dog","lot","log","cog"]5 (hit -> hot -> dot -> dog -> cog).
  • begin = "hit", end = "cog", words = ["hot","dot","dog","lot","log"]0.

Constraints#

  • 1 <= L <= 10, 1 <= words.length <= 5000, all words same length.

Hints#

Hint 1
BFS treats unweighted graph distance as the answer; build adjacency lazily via wildcard patterns.
Hint 2
For each word, generating L wildcards like h*t gives constant-time neighbor lookup against a bucket map.

Approach#

Build a map from each wildcard pattern (e.g., h*t) to the words matching it. BFS from beginWord: for each popped word, for each of its L wildcards, enqueue every bucket-mate not yet visited.

Solution#

Word Ladder
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
unordered_set<string> dict(wordList.begin(), wordList.end());
if (!dict.count(endWord)) return 0;
unordered_map<string, vector<string>> buckets;
int L = beginWord.size();
for (auto& w : dict) {
for (int i = 0; i < L; ++i) {
string key = w;
key[i] = '*';
buckets[key].push_back(w);
}
}
queue<pair<string,int>> q;
q.push({beginWord, 1});
unordered_set<string> seen{beginWord};
while (!q.empty()) {
auto [w, d] = q.front(); q.pop();
if (w == endWord) return d;
for (int i = 0; i < L; ++i) {
string key = w;
key[i] = '*';
auto it = buckets.find(key);
if (it == buckets.end()) continue;
for (auto& nx : it->second) {
if (seen.insert(nx).second) q.push({nx, d + 1});
}
it->second.clear(); // optional dedupe optimization
}
}
return 0;
}
};

Editorial#

The pattern-bucket trick reduces neighbor discovery from O(N * L) per node to O(L) lookups plus the size of each bucket. BFS over an unweighted graph yields the shortest hop count by construction. Clearing buckets after consumption avoids revisiting them on later pops.

Complexity#

  • Time: O(N * L^2) for bucket build, comparable for BFS.
  • Space: O(N * L) for buckets and queue.

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.