127. Word Ladder

Description

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.

For example,

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

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

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.

UPDATE (2017/1/20):
The wordList parameter had been changed to a list of strings (instead of a set of strings). Please reload the code definition to get the latest changes.

Solution

(这道题用DFS会Stack Overflow...)

BFS, time O(n), space O(n)

zz: https://www.jianshu.com/p/753bd585d57e

这道题是经典的广度有优先搜索的例子,也是Dijkstra's algorithm的变形。
以题目给出的例子为例,其实就是在所有路径的权重都为1的情况下求出下列无向图中从节点hit到节点cog的最短路径:

127. Word Ladder_第1张图片
image.png

PS:图中相互之间只相差一个字母的单词都是相邻节点。

利用BFS算法,维持两个集合: visited 和 wordSet

127. Word Ladder_第2张图片
image.png

从hit开始出发,找到唯一的相邻节点:hot, 把它放进visited中,第一次循环结束。 PS: 所谓找到相邻的节点,在题目中就是找出和该单词之相差一个字母的所有单词。请看最后代码的详细实现。

127. Word Ladder_第3张图片
image.png

查看hot节点的所有相邻节点(已经被访问过的hit除外),找到lot和dot, 放进visited中。第二次循环结束。

127. Word Ladder_第4张图片
image.png

找出新家进来的lot和dot的未被访问的相邻节点,分别是log和dog放进visited中。第三次循环结束。

127. Word Ladder_第5张图片
image.png

找出log的未被访问的相邻节点cog,放进结合中。第四次循环结束。由于cog就是endWord,任务结束,跳出循环。

127. Word Ladder_第6张图片
image.png

这里总共经历了四次循环,每循环一次,其实就是从beginWord想endWord变化的一步,因此循环的次数(加上1)就是从beginWord想endWord转变经历的 number of steps。

class Solution {
    public int ladderLength(String beginWord, String endWord, List wordList) {
        Set dict = new HashSet<>(wordList);
        Set preWords = new HashSet<>();
        preWords.add(beginWord);
        int distance = 1;
        
        while (!preWords.contains(endWord)) {
            Set currWords = new HashSet<>();
            
            for (String pre : preWords) {
                char[] arr = pre.toCharArray();
                
                for (int i = 0; i < arr.length; ++i) {
                    char original = arr[i];
                    
                    for (char c = 'a'; c <= 'z'; ++c) {
                        if (c == original) continue;
                        arr[i] = c;
                        String curr = new String(arr);
                        
                        if (dict.contains(curr)) {
                            currWords.add(curr);
                            dict.remove(curr); // to avoid duplicate visit
                        }
                    }
                    
                    arr[i] = original;
                }
            }
            
            if (currWords.isEmpty()) {  // cannot move forward
                return 0;
            }
            
            preWords = currWords;   // switch to next level
            ++distance;
        }
        
        return distance;
    }
}

你可能感兴趣的:(127. Word Ladder)