Advertisement

Word Ladder II - LeetCode 126 Solution

Word Ladder II - Complete Solution Guide

Word Ladder II is LeetCode problem 126, a Hard level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.

Problem Statement

A transformation sequence from word beginWord to word endWord using a dictionary wordList is a sequence of words beginWord -> s 1 -> s 2 -> ... -> s k such that: Every adjacent pair of words differs by a single letter. Every s i for 1 <= i <= k is in wordList . Note that beginWord does not need to be in wordList . s k == endWord Given two words, beginWord and endWord , and a dictionary wordList , return all the shortest transformation sequences from beginWord to endWord , or an empty list if no

Detailed Explanation

The 'Word Ladder II' problem asks you to find all the shortest transformation sequences from a given `beginWord` to an `endWord`, using a provided `wordList` as a dictionary. Each word in the sequence must differ from the previous word by exactly one letter and must be present in the `wordList`. The `beginWord` does not necessarily need to be in the `wordList`. The output is a list of lists, where each inner list represents a shortest transformation sequence. If no such sequence exists, return an empty list.

Solution Approach

The solution uses a combination of Breadth-First Search (BFS) and Depth-First Search (DFS) (backtracking). First, BFS is employed to build an adjacency list representing the graph of possible word transformations, along with the distance (number of transformations) from the `beginWord` to each reachable word. The BFS stops when the `endWord` is found. After BFS, DFS is used to explore the paths from `beginWord` to `endWord` using the adjacency list, constructing all shortest paths. DFS is constrained by only exploring neighbors that are exactly one step further than the current node, as determined by the distances calculated by BFS.

Step-by-Step Algorithm

  1. Step 1: **Initialization:** Create a set `wordSet` from the `wordList` for efficient word lookup. Check if `endWord` is present in `wordSet`. If not, return an empty list because no transformation is possible.
  2. Step 2: **BFS (Breadth-First Search):** Perform a BFS starting from `beginWord`. Use a queue to store words to visit. Maintain a `distance` map to store the distance of each word from `beginWord`. Also, create an `adj` (adjacency list) map to represent the graph of transformations. The BFS explores words level by level.
  3. Step 3: **BFS Exploration:** For each word in the queue, generate all possible one-letter variations. If a variation is present in `wordSet` and has not been visited yet (not in `distance`), add it to the queue, update its distance, and add it to the adjacency list of the current word. If the variation's distance is equal to the current word's distance plus one (meaning it is a shortest path neighbor), also add it to the adjacency list. Stop BFS if endWord is found.
  4. Step 4: **DFS (Depth-First Search / Backtracking):** If the BFS found the `endWord`, start a DFS from `beginWord` to find all shortest paths to `endWord`. Use a `path` list to keep track of the current path being explored. Add the current word to the `path`.
  5. Step 5: **DFS Exploration:** If the current word is the `endWord`, add a copy of the current `path` to the `results` list. Otherwise, for each neighbor of the current word in the `adj` list, recursively call DFS with the neighbor, adding it to the current path and removing it after the recursive call returns (backtracking).
  6. Step 6: **Return:** Return the `results` list containing all shortest transformation sequences.

Key Insights

  • Insight 1: Breadth-First Search (BFS) is crucial for finding the *shortest* paths in an unweighted graph. The graph is implicitly defined by the word list, where edges connect words that differ by one letter.
  • Insight 2: Backtracking (Depth-First Search, or DFS) is necessary to construct *all* the shortest paths once the graph structure and distances are known from the BFS.
  • Insight 3: Efficiently pre-compute the adjacency list. Building it during the backtracking phase would be significantly slower.
  • Insight 4: Optimizing memory usage in C is critical due to manual memory management. Failing to free allocated memory can lead to memory leaks, and incorrect allocation can lead to crashes.
  • Insight 5: The C version uses explicit string duplication (strdup) to manage strings correctly and avoid issues when modifying them. This is crucial for correctness and memory safety.

Complexity Analysis

Time Complexity: O(V*26^L + N)

Space Complexity: O(V^2 + N)

Topics

This problem involves: Hash Table, String, Backtracking, Breadth-First Search.

Companies

Asked at: Citadel, LinkedIn, Lyft, TikTok, Yelp.