Problem
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"]
]
Code
bool isConv(const std::string& s1,const std::string& s2) { int diff = 0; int m = s1.size(); int n = s2.size(); if(m != n) return false; for(int i = 0; i < n; ++i){ if(s1[i] != s2[i]) ++diff; if(diff > 1) return false; } if(diff == 0) return false; return true; } bool inDict(string start,unordered_set<string> &dict) { std::unordered_set<std::string>::const_iterator got = dict.find (start); return ( got != dict.end() ); } vector<string> getWords(string start,unordered_set<string> &dict) { int n = start.size(); vector<string> result; for(int i = 0;i < n; ++i){ string temp = start; for(int j = 0;j < 26; ++j){ if(start[i] != 'a' + j){ temp[i] = 'a' + j; if(inDict(temp,dict)){ result.push_back(temp); } } } } return result; } int findLaddersBFS(std::string start, std::string end, std::unordered_set<std::string> &dict ,map<string,int>& level_num,map<string,set<string> >& pi) { for (auto itr = dict.begin(); itr != dict.end(); ++itr) { level_num[*itr] = INT_MAX; } level_num[start] = 1; level_num[end] = INT_MAX; deque<string> Q; Q.push_back(start); while(!Q.empty()){ string v = Q.front(); Q.pop_front(); int v_level = level_num[v]; int end_level = level_num[end]; if(v_level >= end_level) return end_level; vector<string> words = getWords(v,dict); vector<string>::iterator it = words.begin(); for(; it != words.end(); ++it){ string w = *it; int w_level = level_num[w]; if(w_level > v_level + 1){ pi[w].insert(v); level_num[w] = v_level + 1; if(w_level < end_level && isConv(w,end)){ level_num[end] = v_level + 2; pi[end].insert(w); } else Q.push_back(w); } else if(w_level == v_level + 1){ pi[w].insert(v); if(w_level < end_level && isConv(w,end)){ pi[end].insert(w); } } } } return 0; } void printPi( map<string,set<string> >& pi,const string& end,const string& start,vector<string>& out, int pos,vector<vector<string>>& result){ out[pos] = end; if(start == end){ result.push_back(vector<string>(out.rbegin(),out.rend())); return; } set<string> parents = pi[end]; set<string>::iterator it = parents.begin(); for(;it != parents.end(); ++it){ printPi(pi,*it,start,out,pos + 1,result); } } vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) { // IMPORTANT: Please reset any member data you declared, as // the same Solution instance will be reused for each test case. vector<vector<string>> result; if(isConv(start,end)){ vector<string> tmp(2); tmp[0] = start; tmp[1] = end; result.push_back(tmp); return result; } map<string,int> level_num; map<string,set<string> > pi; int endl_level = findLaddersBFS(start,end,dict,level_num,pi); if(endl_level == 0) return result; vector<string> out(endl_level); printPi(pi,end,start,out,0,result); return result; }
No comments:
Post a Comment