1

1. 题目

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:

Only one letter can be changed at a time
Each intermediate word must exist in the word list
For example,

Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
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.

2. 思路

注释部分提出来:

// 26叉树广度优先遍历,找到end,或者是树无法继续延伸
// 树的延伸是基于当前的字符串,每次变化一个字符[a-z]
// 如果新的字符串在wordlist里就加入候选和延伸队列里
// 由于是广度遍历,第一次找到的候选一定是最短路径的因此
// 可以将找到的候选从dict里删除,避免后续再找到的时候形成死循环
// 要计算是第几层,用一个空字符串来作为层之间的分隔符

这里最坑的地方是标准答案不是求的转移次数,而是求的转移链的链长度,也就是转移一次的情况,长度是2,其他类似的都是大了一。白白耗费了好多时间......

3. 代码

耗时:263ms

class Solution {
public:
    // 26叉树广度优先遍历,找到end,或者是树无法继续延伸
    // 树的延伸是基于当前的字符串,每次变化一个字符[a-z]
    // 如果新的字符串在wordlist里就加入候选和延伸队列里
    // 由于是广度遍历,第一次找到的候选一定是最短路径的因此
    // 可以将找到的候选从dict里删除,避免后续再找到的时候形成死循环
    // 要计算是第几层,用一个空字符串来作为层之间的分隔符
    int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) {
        if (beginWord == endWord) { return 0; }
        if (beginWord.length() == 0) { return 0; }
        wordList.erase(beginWord);
        deque<string> q;
        int step = 2;
        q.push_back(beginWord);
        q.push_back("");
        while (!q.empty()) {
            string s = q.front();
            q.pop_front();
            if (s == "") {
                if (q.empty()) { return 0; }
                q.push_back("");
                step++;
                continue;
            }
            //cout << "s=" << s << endl; 
            for (int w_i = 0; w_i < s.length(); w_i++) {
                char ch = s[w_i];
                for (char ch_i = 'a'; ch_i <= 'z'; ch_i++) {
                    if (ch_i == ch) { continue; }
                    s[w_i] = ch_i;
                    if (s == endWord) {
                        //cout << "find s=" << s << endl;
                        return step; 
                    }
                    if (wordList.find(s) != wordList.end()) {
                        q.push_back(s);
                        wordList.erase(s);
                        //cout << "new s=" << s << endl;
                    }
                    s[w_i] = ch;
                }
            }
        }
        return 0;
    }
};

knzeus
72 声望28 粉丝

行万里路,读万卷书