LeetCode[126.Word Ladder II]题解 难度[hard]

来源:互联网 发布:仁和知柏地黄丸的功效 编辑:程序博客网 时间:2024/06/05 14:19

**

题目

**
Given two words (beginWord and endWord), and a dictionary’s word list, find all shortest transformation sequence(s) from beginWord toendWord, such that:
1. Only one letter can be changed at a time
2. Each intermediate word must exist in the word list
For example,
Given:
beginWord = “hit”
endWord = “cog”
wordList = [“hot”,”dot”,”dog”,”lot”,”log”]
本题是127word ladder加强版,大致意思就是要找出两个单词的所有最短词梯并输出。

**

算法

**
算法思路与第一版word ladder大致相同(详细参考第一版word ladder题解接:http://blog.csdn.net/cs_linyf/article/details/52450201),使用BFS,不同之处是这题要输出最短路径。所以要把变化经过的单词都记录下来,这里可以使用一个map来记录每个单词的前驱是什么,由于路径有多条,前驱不是唯一的,所以映射到一个vector中。当找到目标单词时,词梯中所有单词的前驱都已经记录在这映射中,这里可以用一个递归来还原最短路径。
实现如下:

class Solution {public:    vector<vector<string> > findLadders(string beginWord, string endWord, unordered_set<string> &wordList) {        vector<string> current,next;  //BFS时当前层和下一层        current.push_back(beginWord);         bool exist = false;         while(!current.empty()){                int n = current.size();            for(int i=0; i<n; ++i)      //把当前层的所有单词从字典里删除                 wordList.erase(current[i]);              for(int i=0; i<n; ++i){     //遍历当前层                 string word = current[i];                int word_len = word.size();                for(int j=0; j<word_len; ++j){                      string temp = word;                    for(char x='a'; x<='z'; ++x){                        if(temp[j]!=x){                            temp[j] = x;                                                    if(temp == endWord){                                pre[temp].push_back(word);  //记录前驱                                 exist = true;                                   continue;                             }                               else if(wordList.find(temp)!=wordList.end()){                                pre[temp].push_back(word);                                                          bool put = true;                                if(pre[temp].size()!=1) put = false;     //防止一个单词在next里出现几次                                                         if(put) next.push_back(temp);                            }                                               }                    }                }            }            if(exist) break;    //遍历完当层,最短路已经找完             current.clear();            current = next;            next.clear();        }           if(exist)   generatePaths(beginWord,endWord);        return paths;    }private:    vector<vector<string> > paths;    vector<string> temp_path;    unordered_map<string, vector<string> > pre; //记录单词的前驱     void generatePaths(string beginWord,string endWord){        //用递归找回所有路径         temp_path.push_back(endWord);           if(beginWord == endWord){            int n = temp_path.size();            vector<string> tmp;            for(int i=n-1; i>=0; --i)                tmp.push_back(temp_path[i]);            paths.push_back(tmp);           }        else{            int n = pre[endWord].size();            for(int i=0; i<n; ++i)                generatePaths(beginWord,pre[endWord][i]);        }        temp_path.pop_back();    }};

可以AC,耗时343ms
这里写图片描述

思考:
若本题使用双向BFS应该怎样实现呢?

0 0
原创粉丝点击