您的位置:首页 > 编程语言 > C语言/C++

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

2016-09-11 16:05 543 查看
**

题目

**

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应该怎样实现呢?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ BFS leetcode wordLadder