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"] ]
Note:
- All words have the same length.
- All words contain only lowercase alphabetic characters.
分析:BFS+DFS
用两个unordered_set<string> cur和pre代替queue,cur表示当前层,prev表示上一层。大体思路上超时版本相同,先用bfs产生一个从start到end的最小路径图(通过记录节点前驱)。再用dfs生成从start到end的所有路径。代码如下:
class Solution { public: unordered_map<string, vector<string>> father; vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) { vector<vector<string> > result; if(start == end) return vector<vector<string> >(1, vector<string>(2, start)); unordered_set<string> used; unordered_set<string> prev; bool found = false; prev.insert(start); while(!prev.empty() && !found){ unordered_set<string> cur; for(auto i = prev.begin(); i != prev.end(); i++){ used.insert(*i); string tmp = *i; for(int j = 0; j < tmp.length(); j++) for(char c = 'a'; c <= 'z'; c++) if(tmp[j] != c){ swap(tmp[j], c); if(dict.find(tmp) != dict.end() && used.find(tmp) == used.end() && prev.find(tmp) == prev.end()){ cur.insert(tmp); father[tmp].push_back(*i); if(tmp == end) found = true; } swap(tmp[j], c); } } prev = cur; } if(found){ vector<string> path; generate_path(result, path, start, end); } return result; } void generate_path(vector<vector<string> > &result, vector<string> &path, string start, string s){ path.push_back(s); if(s == start){ result.push_back(path); reverse(result.back().begin(), result.back().end()); }else{ for(auto i = father[s].begin(); i != father[s].end(); i++) generate_path(result, path, start, *i); } path.pop_back(); } };