[LeetCode] 127 Word Ladder

原题地址:

https://leetcode.com/problems/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.

 

解法:

这道题目给定一个开始的单词和一个结束的单词,然后给了一个单词的数组,每次能变换单词的一个字母,要求由开始单词变换到结束单词的最短路径的长度。看似是字符串的题目,但涉及到最短路径,就知道是使用BFS进行解决。

准备一个队列,先把开始单词放进队列里面,每次从队列中拿出一个单词,我们把它称为“当前单词”。当“当前单词”与结束单词一样时,返回当前遍历到的层数。否则,把搜索到与当前单词相差一个字母的单词放进队列里面。每次把一个单词放进队列里面时,把这个单词从单词数组里面删除掉,以防形成环路。

具体实现代码如下:

class Solution {
public:
   bool isConnected(string a, string b) {
       int num = 0;
       for (int i = 0; i < a.size(); i++) {
           if (a[i] != b[i]) num++;
       }
       return num == 1;
  }
   int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        int res = 1;
        queue<string> q;
        q.push(beginWord);
        int count = 1;
        while (!q.empty()) {
            string str = q.front();
            q.pop();
            count--;
            if (str == endWord) return res;
            for (vector<string>::iterator iter = wordList.begin(); iter != wordList.end();) {
                if (isConnected(str, *iter)) {
                    q.push(*iter);
                    iter = wordList.erase(iter);
                }
                else {
                    iter++;
                }
            }
            if (count == 0) {
                count = q.size();
                res++;
            }
        }
        return 0;
    }
};

上面的代码有两点值得去研究的:
(1)

count变量的使用:这是用来计算当前层数的,每当count为0,表明已经把一层的单词都访问过了,层数res加1,然后再把新的一层的单词个数赋给count。这是需要理解一下的地方。

(2)

把单词放进队列时,要把这个单词从原来的数组里面erase掉,避免出现环路。但现在erase掉的单词,为什么就不会在后面使用到呢(不同的路径)?这个我刚做完的时候百思不得其解,后来一想,假如后面使用到了,它也不会是最短的路径(使用到的那一条路径的后半部分和当前路径一模一样),因此可以直接erase掉。

posted @ 2017-10-12 15:55  fengzw  阅读(142)  评论(0编辑  收藏  举报