Skip to main content

Command Palette

Search for a command to run...

Solving Leetcode Interviews in Seconds with AI: Word Ladder II

Updated
4 min read

Introduction

In this blog post, we will explore how to solve the LeetCode problem "126" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.

Problem Statement

A transformation sequence from word beginWord to word endWord using a dictionary wordList is a sequence of words beginWord -> s1 -> s2 -> ... -> sk such that: Every adjacent pair of words differs by a single letter. Every si for 1 <= i <= k is in wordList. Note that beginWord does not need to be in wordList. sk == 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 such sequence exists. Each sequence should be returned as a list of the words [beginWord, s1, s2, ..., sk]. 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"]] Explanation: There are 2 shortest transformation sequences: "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: The endWord "cog" is not in wordList, therefore there is no valid transformation sequence. Constraints: 1 <= beginWord.length <= 5 endWord.length == beginWord.length 1 <= wordList.length <= 500 wordList[i].length == beginWord.length beginWord, endWord, and wordList[i] consist of lowercase English letters. beginWord != endWord All the words in wordList are unique. The sum of all shortest transformation sequences does not exceed 105.

Explanation

Here's a breakdown of the approach, complexities, and the Python code for finding all shortest transformation sequences:

  • Breadth-First Search (BFS): Use BFS to explore the possible word transformations level by level. This guarantees finding the shortest paths first.
  • Graph Representation (Implicit): We don't explicitly build a graph. Instead, we generate neighbors (words one letter apart) on the fly from the wordList during the BFS.
  • Path Tracking: Maintain a dictionary to store the predecessors of each word in the paths we discover. This allows us to reconstruct all shortest paths once we reach the endWord.

  • Runtime Complexity: O(V + E), where V is the number of words in the word list, and E is the number of possible transitions between words (which can be approximated by V 26 L, where L is the word length). Overall, close to O(N*M) where N is the number of words in wordList, and M is the length of a word. Storage complexity: O(V + P), where P is the total length of all shortest paths combined (which can be O(V^2) in worst case scenarios but according to constraints it does not exceed 10^5).

Code

    from collections import defaultdict, deque

def findLadders(beginWord: str, endWord: str, wordList: list[str]) -> list[list[str]]:
    """
    Finds all shortest transformation sequences from beginWord to endWord using words from wordList.

    Args:
        beginWord: The starting word.
        endWord: The target word.
        wordList: A list of words to use in the transformation.

    Returns:
        A list of lists, where each inner list is a shortest transformation sequence.
        Returns an empty list if no such sequence exists.
    """

    if endWord not in wordList:
        return []

    wordList = set(wordList)  # For faster lookup
    queue = deque([(beginWord, [beginWord])])
    visited = {beginWord}
    all_paths = []
    min_length = float('inf')

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

        if len(path) > min_length:
            break # Optimization: Stop if current path exceeds min length

        if word == endWord:
            min_length = len(path)
            all_paths.append(path)
            continue

        for i in range(len(word)):
            for char_code in range(ord('a'), ord('z') + 1):
                new_char = chr(char_code)
                new_word = word[:i] + new_char + word[i + 1:]

                if new_word in wordList and new_word not in visited:
                    new_path = path + [new_word]
                    queue.append((new_word, new_path))
                    visited.add(new_word)

    #Filter out longer paths after BFS
    filtered_paths = [path for path in all_paths if len(path) == min_length]

    return filtered_paths

More from this blog

C

Chatmagic blog

2894 posts