127. Word Ladder

11 阅读1分钟

image.png

BFS

  • We are given a beginWord and an endWord. Let these two represent start node and end node of a graph.
  • The only condition for every step we take on this ladder of words is the current word should change by just one letter.
  • Words as nodes and edges between words which differ by just one letter
  • The problem boils down to finding the shortest path from a start node to a destination node, if there exists one.
  • Hence it can be solved using Breadth First Search approach.

image.png

  • T: O(N × L × 26) = O(N × L) N: number of words in wordList L: length of each word (since all words are the same length)
  • S: O(N × L) space in total (dominated by storing words and queue)
class Solution {
    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        Set<String> set = new HashSet<>(wordList);
        // required!
        if (!set.contains(endWord)) {
            return 0;
        }

        // BFS queue
        Queue<String> queue = new LinkedList<>();
        queue.offer(beginWord);

        // <word, path length to this word>
        Map<String, Integer> map = new HashMap<>();
        map.put(beginWord, 1);

        while (!queue.isEmpty()) {
            String word = queue.poll();
            // for each word in queue:
            // try to substitue one of its char at a time
            for (int i = 0; i < word.length(); i++) {
                char[] arr = word.toCharArray(); // can't be outside
                for (char j = 'a'; j <= 'z'; j++) {
                    arr[i] = j;
                    String newWord = String.valueOf(arr);
                    if (newWord.equals(endWord)) {
                        return map.get(word) + 1;
                    }
                    // after substitute, if new word exists in given dict
                    if (set.contains(newWord) && !map.containsKey(newWord)) {// cant go back
                        queue.offer(newWord);
                        map.put(newWord, map.get(word) + 1);
                    }
                }
            }
        }

        return 0;
    }
}
//  if (!set.contains(endWord)) {
//             return 0; 
//         }
// is required. for example: this still returns 5 without above check
// beginWord = "hit"
// endWord = "cog"
// wordList = ["hot","dot","dog","lot","log"]