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
参考:http://www.cnblogs.com/x1957/p/3526838.html
1.依然是BFS,记录每个的前驱节点father[x],当然这个father有多个;
采用分层遍历,只要到了end,那么这一层所有的都是最短的,一样长。
2.然后用DFS遍历father,从end到start
DFS递归完注意‘恢复现场’。
class Solution {
public:
/**
* @param start, a string
* @param end, a string
* @param dict, a set of string
* @return a list of lists of string
*/
void dfs(vector<vector<string>> &res,unordered_map<string,vector<string>> &father,
vector<string> &path,string &start,string &end){
path.push_back(end);
if(end==start){
vector<string> tmp(path);
reverse(tmp.begin(),tmp.end());
res.push_back(tmp);
path.pop_back();
return;
}
vector<string> fa=father[end];
for(int i=0;i<fa.size();i++){
string f=fa[i];
dfs(res,father,path,start,f);
}
path.pop_back();
}
vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
// write your code here
vector<vector<string>> res;
/*这里需要用set而不能用vector,会使得得到相同的最短路径*/
unordered_set<string> current,next;
unordered_set<string> visited;
unordered_map<string,vector<string>> father;
current.insert(start);
bool found=false;
while (!current.empty() && !found){
for(string str:current){
visited.insert(str);
}
for (string front:current){
for (int i = 0; i < front.size(); i++){
for (int ch = 'a'; ch <= 'z'; ch++){
if(front[i]==ch) continue;
string tmp = front;
tmp[i] = ch;
if (tmp == end){
found=true;
}
if (dict.find(tmp)!=dict.end() && visited.find(tmp)==visited.end() ){
father[tmp].push_back(front);
next.insert(tmp);
}
}
}
}
current.clear();
swap(current,next);
}
if(found){
vector<string> path;
dfs(res,father,path,start,end);
}
return res;
}
};