Word Ladder In C,CPP,JAVA,PYTHON,C#,JS

Spread the love
A close-up shot of a person coding on a laptop, focusing on the hands and screen.

Problem: Word Ladder

Problem Statement:

Given two words, beginWord and endWord, and a dictionary wordList, find the length of the shortest transformation sequence from beginWord to endWord, such that:

  • Only one letter can be changed at a time.
  • Each transformed word must exist in the dictionary.

Note:

  • You must implement a function that returns the length of the shortest transformation sequence.
  • If there is no such transformation sequence, return 0.

Example 1:

Input:

beginWord = "hit"
endWord = "cog"
wordList = ["hot", "dot", "dog", "lot", "log", "cog"]

Output:

5

Explanation: The shortest transformation sequence is "hit" -> "hot" -> "dot" -> "dog" -> "cog", which is 5 words long.

Example 2:

Input:

beginWord = "hit"
endWord = "cog"
wordList = ["hot", "dot", "dog", "lot", "log"]

Output:

0

Explanation: There is no possible transformation sequence from hit to cog because the word cog is not in the word list.

Approach:

The problem can be thought of as finding the shortest path in an unweighted graph, where:

  • Each word in the word list is a node.
  • An edge exists between two nodes (words) if they differ by exactly one character.

Steps:

  1. BFS (Breadth-First Search) is the optimal approach for finding the shortest path in an unweighted graph. We explore all possible transformations from the beginWord to find the shortest path to endWord.
  2. Each word in the BFS queue is associated with the number of steps taken to reach that word.
  3. As soon as we reach the endWord, we return the number of steps (which represents the length of the transformation sequence).
  4. If we exhaust the queue without finding endWord, return 0.

Time Complexity:

  • Time Complexity: O(N×M)O(N \times M)O(N×M), where N is the number of words in the word list and M is the length of each word. This is because for each word, we generate all possible intermediate words by replacing each character one by one.
  • Space Complexity: O(N)O(N)O(N), since we store the word list and BFS queue.

Algorithm:

  1. Start BFS from the beginWord.
  2. For each word, generate all possible words by changing each character to * and check if it’s in the dictionary (word list).
  3. Track the level (or depth) of BFS.
  4. If we reach the endWord, return the number of steps taken.
  5. If no transformation is possible, return 0.

Code Implementations


1. Python Code

from collections import deque

def ladderLength(beginWord, endWord, wordList):
if endWord not in wordList:
return 0

wordList.add(beginWord)
queue = deque([(beginWord, 1)]) # (current_word, current_length)
visited = set([beginWord])

while queue:
word, length = queue.popleft()

# Try changing each character of the word
for i in range(len(word)):
for c in 'abcdefghijklmnopqrstuvwxyz':
new_word = word[:i] + c + word[i+1:]

if new_word == endWord:
return length + 1

if new_word in wordList and new_word not in visited:
visited.add(new_word)
queue.append((new_word, length + 1))

return 0

# Example test cases
beginWord = "hit"
endWord = "cog"
wordList = set(["hot", "dot", "dog", "lot", "log", "cog"])
print(ladderLength(beginWord, endWord, wordList)) # Output: 5

2. C++ Code

#include <iostream>
#include <unordered_set>
#include <queue>
#include <string>
using namespace std;

int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) {
if (wordList.find(endWord) == wordList.end()) return 0;

wordList.insert(beginWord);
queue<pair<string, int>> q; // {current_word, length}
unordered_set<string> visited;
q.push({beginWord, 1});
visited.insert(beginWord);

while (!q.empty()) {
auto [word, length] = q.front();
q.pop();

// Try changing each character of the word
for (int i = 0; i < word.length(); i++) {
char original = word[i];
for (char c = 'a'; c <= 'z'; c++) {
word[i] = c;
if (word == endWord) return length + 1;

if (wordList.find(word) != wordList.end() && visited.find(word) == visited.end()) {
visited.insert(word);
q.push({word, length + 1});
}
}
word[i] = original; // Restore original character
}
}

return 0;
}

int main() {
string beginWord = "hit";
string endWord = "cog";
unordered_set<string> wordList = {"hot", "dot", "dog", "lot", "log", "cog"};
cout << ladderLength(beginWord, endWord, wordList) << endl; // Output: 5
return 0;
}

3. Java Code

import java.util.*;

public class WordLadder {
public int ladderLength(String beginWord, String endWord, Set<String> wordList) {
if (!wordList.contains(endWord)) return 0;

wordList.add(beginWord);
Queue<Pair<String, Integer>> queue = new LinkedList<>();
Set<String> visited = new HashSet<>();
queue.offer(new Pair<>(beginWord, 1));
visited.add(beginWord);

while (!queue.isEmpty()) {
Pair<String, Integer> current = queue.poll();
String word = current.getKey();
int length = current.getValue();

for (int i = 0; i < word.length(); i++) {
char[] temp = word.toCharArray();
for (char c = 'a'; c <= 'z'; c++) {
temp[i] = c;
String newWord = new String(temp);

if (newWord.equals(endWord)) return length + 1;

if (wordList.contains(newWord) && !visited.contains(newWord)) {
visited.add(newWord);
queue.offer(new Pair<>(newWord, length + 1));
}
}
}
}

return 0;
}

public static void main(String[] args) {
WordLadder wl = new WordLadder();
Set<String> wordList = new HashSet<>(Arrays.asList("hot", "dot", "dog", "lot", "log", "cog"));
System.out.println(wl.ladderLength("hit", "cog", wordList)); // Output: 5
}
}

class Pair<K, V> {
K key;
V value;

public Pair(K key, V value) {
this.key = key;
this.value = value;
}

public K getKey() { return key; }
public V getValue() { return value; }
}

4. C# Code

using System;
using System.Collections.Generic;

public class WordLadder {
public int LadderLength(string beginWord, string endWord, HashSet<string> wordList) {
if (!wordList.Contains(endWord)) return 0;

wordList.Add(beginWord);
Queue<KeyValuePair<string, int>> queue = new Queue<KeyValuePair<string, int>>();
HashSet<string> visited = new HashSet<string>();
queue.Enqueue(new KeyValuePair<string, int>(beginWord, 1));
visited.Add(beginWord);

while (queue.Count > 0) {
var current = queue.Dequeue();
string word = current.Key;
int length = current.Value;

for (int i = 0; i < word.Length; i++) {
char[] temp = word.ToCharArray();
for (char c = 'a'; c <= 'z'; c++) {
temp[i] = c;
string newWord = new string(temp);

if (newWord == endWord) return length + 1;

if (wordList.Contains(newWord) && !visited.Contains(newWord)) {
visited.Add(newWord);
queue.Enqueue(new KeyValuePair<string, int>(newWord, length + 1));
}
}
}
}

return 0;
}

public static void Main() {
WordLadder wl = new WordLadder();
HashSet<string> wordList = new HashSet<string> { "hot", "dot", "dog", "lot", "log", "cog" };
Console.WriteLine(wl.LadderLength("hit", "cog", wordList)); // Output: 5
}
}

5. JavaScript Code

function ladderLength(beginWord, endWord, wordList) {
if (!wordList.has(endWord)) return 0;

wordList.add(beginWord);
let queue = [[beginWord, 1]]; // [current_word, current_length]
let visited = new Set([beginWord]);

while (queue.length > 0) {
let [word, length] = queue.shift();

for (let i = 0; i < word.length; i++) {
for (let c = 'a'; c <= 'z'; c++) {
let newWord = word.slice(0, i) + c + word.slice(i + 1);

if (newWord === endWord) return length + 1;

if (wordList.has(newWord) && !visited.has(newWord)) {
visited.add(newWord);
queue.push([newWord, length + 1]);
}
}
}
}

return 0;
}

// Example test cases
let beginWord = "hit";
let endWord = "cog";
let wordList = new Set(["hot", "dot", "dog", "lot", "log", "cog"]);
console.log(ladderLength(beginWord, endWord, wordList)); // Output: 5

Summary of Code Logic:

  1. BFS: We use BFS to explore all possible transformations, layer by layer, until we find the shortest transformation sequence.
  2. Word Generation: For each word, we generate all possible words by changing one character at a time, checking if they are valid transformations (i.e., present in the dictionary).
  3. Visited Set: We maintain a visited set to avoid revisiting words and getting stuck in infinite loops.
  4. Queue: We store each word in the queue with its current transformation length.

Time Complexity:

  • Time Complexity: O(N×M)O(N \times M)O(N×M), where N is the number of words and M is the length of each word.
  • Space Complexity: O(N)O(N)O(N), for storing words in the visited set and the queue.