Problem: Word Ladder II Problem Statement: Given two words, beginWord and endWord, and a dictionary wordList, find all shortest transformation sequences from beginWord to endWord, such that: Example 1: Input: beginWord = “hit”endWord = “cog”wordList = [“hot”, “dot”, “dog”, “lot”, “log”, “cog”] Output: [[“hit”, “hot”, “dot”, “dog”, “cog”], [“hit”, “hot”, “lot”, “log”, “cog”]] Example 2: Input: beginWord = “hit”endWord = “cog”wordList = [“hot”, “dot”, “dog”, “lot”, “log”] Output: [] Explanation: There is no possible transformation sequence from hit to cog because the word cog is not in the word list. Approach: The problem is essentially about finding the shortest paths in an unweighted graph, where each word is a node, and an edge exists between two nodes if one can be obtained by changing exactly one character. We can break the solution down into two major steps: Step 1: Breadth-First Search (BFS) Step 2: Backtracking Time Complexity: Algorithm: Code Implementation: 1. Python Code from collections import deque, defaultdictdef findLadders(beginWord, endWord, wordList): # Step 1: Edge case – If endWord is not in wordList, return an empty list. if endWord not in wordList: return [] # Step 2: Build a dictionary of all possible intermediate words wordList.add(beginWord) neighbors = defaultdict(list) for word in wordList: for i in range(len(word)): pattern = word[:i] + ‘*’ + word[i+1:] neighbors[pattern].append(word) # Step 3: BFS to find the shortest path length level = {beginWord: [[beginWord]]} # Map to keep track of paths queue = deque([beginWord]) found = False while queue and not found: visited = set() # Keep track of words visited in this level for _ in range(len(queue)): word = queue.popleft() for i in range(len(word)): pattern = word[:i] + ‘*’ + word[i+1:] for neighbor in neighbors[pattern]: if neighbor not in level: level[neighbor] = [] if neighbor not in visited: visited.add(neighbor) queue.append(neighbor) # Add the new word to all the possible paths if neighbor == endWord: found = True for path in level[word]: level[neighbor].append(path + [neighbor]) # Move to the next level, after exploring all nodes for the current level for word in visited: level[word] = [path for path in level[word] if path[-1] == word] # Step 4: Return the result return level[endWord]# Example test casebeginWord = “hit”endWord = “cog”wordList = {“hot”, “dot”, “dog”, “lot”, “log”, “cog”}result = findLadders(beginWord, endWord, wordList)print(result) Explanation of the Python Code: 2. C++ Code #include <iostream>#include <vector>#include <unordered_set>#include <unordered_map>#include <queue>#include <string>using namespace std;vector<vector<string>> findLadders(string beginWord, string endWord, unordered_set<string>& wordList) { vector<vector<string>> result; if (wordList.find(endWord) == wordList.end()) return result; unordered_map<string, vector<vector<string>>> level; // to store the paths at each level unordered_set<string> currentLevel, nextLevel; currentLevel.insert(beginWord); wordList.insert(endWord); bool found = false; while (!currentLevel.empty() && !found) { for (auto& word : currentLevel) wordList.erase(word); // Remove words at this level nextLevel.clear(); for (auto& word : currentLevel) { string temp = word; for (int i = 0; i < word.length(); i++) { char original = temp[i]; temp[i] = ‘*’; // Replace character with * for (auto& neighbor : wordList) { if (neighbor == temp) { if (neighbor == endWord) found = true; for (auto& path : level[word]) { level[neighbor].push_back(path); } nextLevel.insert(neighbor); } } temp[i] = original; } } currentLevel.swap(nextLevel); } for (auto& path : level[endWord]) { result.push_back(path); } return result;}int main() { string beginWord = “hit”, endWord = “cog”; unordered_set<string> wordList = {“hot”, “dot”, “dog”, “lot”, “log”, “cog”}; vector<vector<string>> result = findLadders(beginWord, endWord, wordList); for (const auto& path : result) { for (const auto& word : path) { cout << word << ” “; } cout << endl; } return 0;} Explanation of C++ Code: 3. Java Code import java.util.*;public class WordLadderII { public List<List<String>> findLadders(String beginWord, String endWord, Set<String> wordList) { List<List<String>> result = new ArrayList<>(); if (!wordList.contains(endWord)) return result; Map<String, List<List<String>>> level = new HashMap<>(); Set<String> currentLevel = new HashSet<>(); Set<String> nextLevel = new HashSet<>(); currentLevel.add(beginWord); wordList.add(endWord); boolean found = false; while (!currentLevel.isEmpty() && !found) { for (String word : currentLevel) wordList.remove(word); // Remove words at this level nextLevel.clear(); for (String word : currentLevel) { char[] temp = word.toCharArray(); for (int i = 0; i < temp.length; i++) { char original = temp[i]; temp[i] = ‘*’; // Replace character with * String pattern = new String(temp); if (wordList.contains(pattern)) { if (pattern.equals(endWord)) found = true; for (List<String> path : level.getOrDefault(word, new ArrayList<>())) { List<String> newPath = new ArrayList<>(path); newPath.add(pattern); level.computeIfAbsent(pattern, k -> new ArrayList<>()).add(newPath); } nextLevel.add(pattern); } temp[i] = original; // Restore original character } } currentLevel = nextLevel; } return level.getOrDefault(endWord, new ArrayList<>()); } public static void main(String[] args) { WordLadderII wl = new WordLadderII(); Set<String> wordList = new HashSet<>(Arrays.asList(“hot”, “dot”, “dog”, “lot”, “log”, “cog”)); List<List<String>> result = wl.findLadders(“hit”, “cog”, wordList); for (List<String> path : result) { System.out.println(path); } }} Explanation of Java Code: C Code #include <stdio.h>#include <string.h>#include <stdlib.h>#include <stdbool.h>#include <ctype.h>#include <limits.h>#define MAX_WORDS 1000#define WORD_LENGTH 10typedef struct Node { char word[WORD_LENGTH]; struct Node* next;} Node;typedef struct Queue { Node* front; Node* rear;} Queue;Queue* createQueue() { Queue* queue = (Queue*)malloc(sizeof(Queue)); queue->front = queue->rear = NULL; return queue;}void enqueue(Queue* queue, char* word) { Node* temp = (Node*)malloc(sizeof(Node)); strcpy(temp->word, word); temp->next = NULL; if (queue->rear) { queue->rear->next = temp; } else { queue->front = temp; } queue->rear = temp;}char* dequeue(Queue* queue) { if (queue->front == NULL) return NULL; Node* temp = queue->front; queue->front = queue->front->next; if (queue->front == NULL) { queue->rear = NULL; } char* word = temp->word; free(temp); return word;}bool isAdjacent(char* word1, char* word2) { int diff = 0; for (int i = 0; word1[i] != ‘\0’; i++) { if (word1[i] != word2[i]) { diff++; } if (diff > 1) return false; } return diff == 1;}void findLadders(char* beginWord, char* endWord, char* wordList[], int wordCount) { // BFS approach to find shortest paths Queue* queue = createQueue(); enqueue(queue, beginWord); while (queue->front != NULL) { char* current = dequeue(queue); // If current word is endWord, stop and print the path if (strcmp(current, endWord) == 0) { printf(“Found transformation sequence\n”); return; } for (int i = 0; i < wordCount; i++) { if (isAdjacent(current, wordList[i])) { enqueue(queue, wordList[i]); } } } printf(“No transformation found\n”);}int main() { char* wordList[] = {“hot”, “dot”, “dog”, “lot”, “log”, “cog”}; int wordCount