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"] ]
以下思路(Leetcode的discuss中,代码也是,以后自己重新写):
solution:
1) first use bfs to create the graph(即unordered_multimap<string, string> path_map,每个元素由2个string组成,
key表示路径中的当前字符串,value表示当前字符串的前一个字符串),
and by using data structure like unorderedmultimap and unorderedset,
I can enhance the speed, one important thing is to change letter to get the interval word,
not by comparing each word in the dict.
2) after getting the graph, use dfs to find all the paths from start to end.(主要理解path_map.equal_range(curr);map的成员函数equal_range,
使用此函数得到一个字符串的多个前驱字符串,然后每个前驱字符串进行dfs,即深度优先搜索(这里用的递归)得到path值)
class Solution { public: unordered_multimap<string, string> path_map; vector<vector<string> > res; unordered_set<string> visited; vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) { dict.insert(start); dict.insert(end); dict.erase(start); path_map.clear(); unordered_set<string> last_layer, curr_layer; curr_layer.insert(start); while (!last_layer.empty() || !curr_layer.empty()) {//得到path_map,每个元素由2个string组成,key表示路径中的当前字符串,value表示当前字符串的前一个字符串 for (unordered_set<string>::iterator cit = last_layer.begin(); cit != last_layer.end(); ++cit) { dict.erase(*cit); } last_layer.clear(); for (unordered_set<string>::iterator cit = curr_layer.begin(); cit != curr_layer.end(); ++cit) { //找到上一层所有字符串的相邻字符串 string cur = *cit; for (int i = 0; i < cur.size(); ++i) { string handle_str = cur; int stop = handle_str[i] - 'a'; for (int j = (stop+1)%26; j != stop; j = (j+1)%26) { handle_str[i] = 'a' + j; if (dict.find(handle_str) != dict.end()) { last_layer.insert(handle_str); path_map.insert(pair<string, string>(handle_str, cur)); } } } } if (last_layer.count(end)) break; curr_layer = last_layer; } vector<string> path; if (!path_map.empty()) get_path(end, start, path); return res; } void get_path(string curr, string start, vector<string> path) {////在path_map中从end开始开始查到start if (curr == start) { path.insert(path.begin(), start); res.push_back(path); //path.clear(); return; } unordered_multimap<string, string>::iterator it; pair<unordered_multimap<string, string>::iterator, unordered_multimap<string, string>::iterator> itrangexx = path_map.equal_range(curr); it = itrangexx.first; while (true) { path.insert(path.begin(), curr);//在path.begin()前面插入值为curr的元素 if (it != path_map.end() && it != itrangexx.second && visited.find(it->second) != visited.end()) { ++it; } if (it == itrangexx.second || it == path_map.end()) break; else { string prev; prev = it->second; visited.insert(prev); get_path(prev, start, path); visited.erase(prev); if (!path.empty()) path.erase(path.begin()); } ++it; } } };