Question :
Given two words (startandend), and a dictionary, find all shortest transformation sequence(s) fromstarttoend, such that:
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:
For Example:
Graph Array = [
h i t
h o t
d o t
d o g
l o t
l o g
c o g
]
Anwser 1 :
class Solution { public: vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) { // Start typing your C/C++ solution below // DO NOT write int main() function if (dict.find(start) == dict.end()) { dict.insert(start); } if (dict.find(end) == dict.end()) { dict.insert(end); } queue<string> q; unordered_map<string, pair<int, vector<string> > > dep_map; dep_map[start] = pair<int, vector<string> >(1, vector<string>()); q.push(start); int depth = 1; int len = start.length(); // word length int min_depth = dict.size() + 2; // 2 for start and end words while (!q.empty() && min_depth > depth) { string cur = q.front(); q.pop(); depth = dep_map[cur].first; for (int i=0; i<len; ++i) // check word(s) { string adj = cur; for (char a='a'; a<='z'; ++a) { if (a==cur[i]) continue; adj[i] = a; if (adj == end) { min_depth = depth+1; } if (dict.find(adj) != dict.end()) { unordered_map<string, pair<int, vector<string> > > ::iterator it = dep_map.find(adj); if(it == dep_map.end()) { pair<int, vector<string> > value(depth + 1, vector<string>()); value.second.push_back(cur); dep_map[adj] = value; q.push(adj); } else if ((it->second).first == depth+1) { it->second.second.push_back(cur); } } } } } // end while vector<vector<string> > result; if (min_depth == dict.size() + 2) { // only for start and end words return result; } vector<string> stack; vector<string> sequence; stack.push_back(end); while(!stack.empty()) { string top = stack.back(); stack.pop_back(); sequence.push_back(top); vector<string> &sons = dep_map[top].second; for(int i=0; i<sons.size(); ++i) { stack.push_back(sons[i]); } if (sons.size()==0) { int index = result.size(); result.push_back(vector<string>()); for (int i=sequence.size()-1; i>=0; --i) { result[index].push_back(sequence[i]); // save result } top = sequence.back(); sequence.pop_back(); while(!sequence.empty()) { string father = sequence.back(); vector<string> brothers = dep_map[father].second; if (top != brothers[0]) { break; } sequence.pop_back(); top = father; } } } return result; } };
Anwser 2 :
class Solution { public: struct Node { vector<string> parent; int layer; }; void buildResult( vector<vector<string>> &result, list<string> &r, string start, string end, unordered_map<string, Node> &checkmap) { r.push_front(end); if(end==start) { vector<string> oneresult(r.begin(), r.end()); result.push_back(oneresult); } else { for(const string &s:checkmap[end].parent) { buildResult(result, r, start, s, checkmap); } } r.pop_front(); } vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) { // Start typing your C/C++ solution below // DO NOT write int main() function unordered_map<string, Node> checkmap; list<string> layer; checkmap[start].layer = 1; checkmap[start].parent.push_back(start); layer.push_back(start); vector<vector<string>> result; bool hasfind = false; string layerend = start; string last; while(!layer.empty()) { string s = layer.front(); layer.pop_front(); int currentlayer = checkmap[s].layer; int L = s.size(); for(int i = 0; i< L; i++) { string temp = s; for(int j = 0; j < 26; j++) { temp[i] = j+'a'; if(temp==end) { checkmap[temp].parent.push_back(s); checkmap[temp].layer = checkmap[s].layer+1; hasfind = true; } else if(dict.count(temp)&&s!=temp) { if(checkmap.count(temp)==0){ checkmap[temp].parent.push_back(s); checkmap[temp].layer = checkmap[s].layer+1; layer.push_back(temp); last = temp; } else if(checkmap[s].layer<checkmap[temp].layer) { checkmap[temp].parent.push_back(s); } } } } // end for if(s == layerend) { layerend = last; if(hasfind) { list<string> r; buildResult(result, r, start, end, checkmap); break; } } } // end while return result; } };
参考推荐: