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:

  1. Return 0 if there is no such transformation sequence.
  2. All words have the same length.
  3. All words contain only lowercase alphabetic characters.
  4. You may assume no duplicates in the word list.
  5. 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.

方法1: bfs

思路:

从beginWord开始,每次尝试将某个位置上的字母变成’a’ - 'z’中的一个,这些变化中,有哪些是在dictionary里面的,我们就有可能在该单词的基础上继续变化,向下搜索。此时要注意几点:

  1. 每次变化都要记录一个和始发点的距离,而第一次找到endword的单词,一定是距离最短的。这也是bfs的特点。
  2. 因此,我们需要将每次遇到的单词从dictionary中去掉遇到过的单词:第一是因为,没有必要再保留这个单词,下一次遇到时所经过的变化次数,一定更多。第二是因为,如果保留,会出现相邻两层之间死循环的情况。第三,自己和自己之间就会出现死循环。

127. Word Ladder
127. Word Ladder
127. Word Ladder

Complexity

Time complexity: O(n ^26len),


class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        set<string> wordSet(wordList.begin(), wordList.end());
        if (wordSet.empty() || !wordSet.count(endWord)) return 0;
        
        queue<string> q;
        q.push(beginWord);
        int level = 1;
        while (!q.empty()) {
            int size = q.size();
            for (int i = 0; i < size; i++) {
                string top = q.front();
                q.pop();
                
                for (int j = 0; j < top.size(); j++) {
                    for (char change = 'a'; change < 'z'; change++) {
                        string next = top;
                        next[j] = change;
                        
                        if (next == endWord) return level + 1;
                        
                        if (wordSet.count(next)) {
                            q.push(next);
                            wordSet.erase(next);
                        }
                    }
                }
            }
            level++;
        }
        return 0;
    }
};

方法2: bidirectional bfs

huahua: https://zxi.mytechroad.com/blog/searching/127-word-ladder/

思路:

Complexity

Time complexity: O(n ^26len/2),

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        set<string> wordSet(wordList.begin(), wordList.end());
        if (!wordSet.count(endWord)) return 0;
        
        queue<string> q1, q2;
        unordered_map<string, int> visited1, visited2;
        q1.push(beginWord);
        q2.push(endWord);
        visited1.insert({beginWord, 1});
        visited2.insert({endWord, 1});
        int level1 = 1, level2 = 1;
        while (!q1.empty() && !q2.empty()) {
            int size1 = q1.size();
            for (int i = 0; i < size1; i++) {
                string top = q1.front();
                q1.pop();
                
                for (int j = 0; j < top.size(); j++) {
                    for (char change = 'a'; change < 'z'; change++) {
                        string next = top;
                        next[j] = change;
                        
                        if (visited2.count(next)) return level1 + visited2[next];
                        
                        if (wordSet.count(next)) {
                            visited1.insert({next, level1 + 1});
                            q1.push(next);
                            wordSet.erase(next);
                        }
                    }
                }
            }
            level1++;
            
            
            int size2 = q2.size();
            for (int i = 0; i < size2; i++) {
                string top = q2.front();
                q2.pop();
                
                for (int j = 0; j < top.size(); j++) {
                    for (char change = 'a'; change < 'z'; change++) {
                        string next = top;
                        next[j] = change;
                        
                        if (visited1.count(next)) return level2 + visited1[next];
                        
                        if (wordSet.count(next)) {
                            visited2.insert({next, level2 + 1});
                            q2.push(next);
                            wordSet.erase(next);
                        }
                    }
                }
            }
            level2++;
        }
        return 0;
    }
};

相关文章:

  • 2021-08-17
  • 2021-08-23
  • 2021-08-09
  • 2021-05-26
  • 2021-08-02
  • 2021-06-07
  • 2022-12-23
猜你喜欢
  • 2021-09-02
  • 2022-01-30
  • 2021-06-02
  • 2021-09-09
相关资源
相似解决方案