Back to Leetcode Go

127. Word Ladder

website/content.en/ChapterFour/0100~0199/0127.Word-Ladder.md

1.7.973.6 KB
Original Source

127. Word Ladder

Problem

Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:

  1. Only one letter can be changed at a time.
  2. Each transformed word must exist in the word list. Note that beginWord is not a transformed word.

Note:

  • Return 0 if there is no such transformation sequence.
  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
  • You may assume no duplicates in the word list.
  • You may assume beginWord and endWord are non-empty and are not the same.

Example 1:

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

Output: 5

Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.

Example 2:

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

Output: 0

Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.

Problem Summary

Given two words (beginWord and endWord) and a dictionary, find the length of the shortest transformation sequence from beginWord to endWord. The transformation must follow these rules:

  1. Only one letter can be changed at a time.
  2. The intermediate words during the transformation must be words in the dictionary.

Notes:

  • If no such transformation sequence exists, return 0.
  • All words have the same length.
  • All words consist only of lowercase letters.
  • There are no duplicate words in the dictionary.
  • You may assume beginWord and endWord are non-empty and are not the same.

Solution Approach

  • This problem requires outputting the shortest number of transformations from beginWord to endWord. BFS can be used. Start from beginWord, change each letter of the word once using 'a'~'z', and look up the generated words in wordList; here, use a Map to record the lookup. If found, enqueue it; if not found, output 0. After enqueuing, traverse sequentially according to the BFS algorithm. When all words have been dequeued and len(queue)<=0, the whole program ends.
  • Although the problem says to find a shortest path, the method for finding the shortest path has actually already been given:
    1. Change only one letter at a time
    2. Each transformation must be in wordList
      So there is no need to separately consider which method is the shortest.

Code

go

package leetcode

func ladderLength(beginWord string, endWord string, wordList []string) int {
	wordMap, que, depth := getWordMap(wordList, beginWord), []string{beginWord}, 0
	for len(que) > 0 {
		depth++
		qlen := len(que)
		for i := 0; i < qlen; i++ {
			word := que[0]
			que = que[1:]
			candidates := getCandidates(word)
			for _, candidate := range candidates {
				if _, ok := wordMap[candidate]; ok {
					if candidate == endWord {
						return depth + 1
					}
					delete(wordMap, candidate)
					que = append(que, candidate)
				}
			}
		}
	}
	return 0
}

func getWordMap(wordList []string, beginWord string) map[string]int {
	wordMap := make(map[string]int)
	for i, word := range wordList {
		if _, ok := wordMap[word]; !ok {
			if word != beginWord {
				wordMap[word] = i
			}
		}
	}
	return wordMap
}

func getCandidates(word string) []string {
	var res []string
	for i := 0; i < 26; i++ {
		for j := 0; j < len(word); j++ {
			if word[j] != byte(int('a')+i) {
				res = append(res, word[:j]+string(int('a')+i)+word[j+1:])
			}
		}
	}
	return res
}