Word Ladder II
Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:
- Only one letter can be changed at a time
- Each intermediate word must exist in the dictionary
For example,
Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
Return
[ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ]在wordLadder 基础上,需要记录路径,记录前驱节点,最后使用深搜来查找路径。要保证路径最短,那么要注意同层之间不能互指,访问过的结点不能再访问。
学习自:https://gitcafe.com/soulmachine/LeetCode
class Solution {
public:
vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict) {
unordered_set<string> visited; //判重
unordered_set<string> current,next; //当前层和下一层,用集合是为了去重
unordered_map<string,vector<string> > father;
int level=0; //层数
bool found=false;
current.insert(start);
while(!current.empty() && !found){
++level;
//将本层全部置为已访问,防止同层之间互指,导致路径非最短
for(auto word : current)
visited.insert(word);
for(auto word : current){
for(size_t i=0;i<word.size();++i){
string new_word=word;
for(char c='a';c<='z';c++){
if(c==new_word[i])continue;
swap(c,new_word[i]);
if(new_word==end)found=true; //找到了
if(visited.count(new_word)==0
&& (dict.count(new_word)>0 || new_word==end)){
next.insert(new_word);
father[new_word].push_back(word);
}
swap(c,new_word[i]);
}
}
}
current.clear();
swap(current,next);
}
vector<vector<string> > result;
if(found){
vector<string> path;
buildPath(father,path,start,end,result);
}
return result;
}
private:
void buildPath(unordered_map<string,vector<string> > &father,
vector<string> &path,const string &start,const string &word,
vector<vector<string> > &result){
path.push_back(word);
if(start==word){
result.push_back(path);
reverse(result.back().begin(),result.back().end());
}else{
for (auto f : father[word])
buildPath(father,path,start,f,result);
}
path.pop_back();
}
};