Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, 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:
List<List<String>> result; List<String> solu; Map<String, List<String>> map; public void findDict2(String str, Set<String> dict, Set<String> nextSet){ int len = str.length(); for(int i=0;i<len;i++){ StringBuffer sBuffer = new StringBuffer(str); for(char j='a';j<='z';j++){ if(sBuffer.charAt(i)==j) continue; sBuffer.replace(i, i+1, ""+j); if(dict.contains(sBuffer.toString())){ nextSet.add(sBuffer.toString()); if(map.containsKey(sBuffer.toString())) map.get(sBuffer.toString()).add(str); else { List<String> pres = new ArrayList<>(); pres.add(str); map.put(sBuffer.toString(), pres); } } } } } public List<List<String>> findLadders(String start, String end, Set<String> dict) { map = new HashMap<>(); result = new ArrayList<>(); solu = new ArrayList<>(); dict.add(start); dict.add(end); Set<String> curSet = new HashSet<>(); curSet.add(start); Set<String> nextSet = new HashSet<>(); solu.add(end); while(dict.size()>0){ Iterator<String> iterator = curSet.iterator(); while(iterator.hasNext()){ String str = iterator.next(); dict.remove(str); } Iterator<String> iterator2 = curSet.iterator(); while(iterator2.hasNext()){ findDict2(iterator2.next(), dict, nextSet); } if(nextSet.isEmpty()) return result; if(nextSet.contains(end)){ output(start, end); return result; } curSet.clear(); curSet.addAll(nextSet); nextSet.clear(); } return result; } public void output(String start, String end){ if(end.equals(start)){ Collections.reverse(solu); result.add(new ArrayList<>(solu)); Collections.reverse(solu); }else { for(int i=0;i<map.get(end).size();i++){ solu.add(map.get(end).get(i)); output(start, map.get(end).get(i)); solu.remove(solu.size()-1); } } }
public: unordered_map<string,vector<string> > mp; // result map vector<vector<string> > res; vector<string> path; void findDict2(string str, unordered_set<string> &dict,unordered_set<string> &next_lev){ int sz = str.size(); string s = str; for (int i=0;i<sz;i++){ s = str; for (char j = 'a'; j<='z'; j++){ s[i]=j; if (dict.find(s)!=dict.end()){ next_lev.insert(s); mp[s].push_back(str); } } } } void output(string &start,string last){ if (last==start){ reverse(path.begin(),path.end()); res.push_back(path); reverse(path.begin(),path.end()); }else{ for (int i=0;i<mp[last].size();i++){ path.push_back(mp[last][i]); output(start,mp[last][i]); path.pop_back(); } } } vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) { mp.clear(); res.clear(); path.clear(); dict.insert(start); dict.insert(end); unordered_set<string> cur_lev; cur_lev.insert(start); unordered_set<string> next_lev; path.push_back(end); while (true){ for (auto it = cur_lev.begin();it!=cur_lev.end();it++){dict.erase(*it);} //delete previous level words for (auto it = cur_lev.begin();it!=cur_lev.end();it++){ //find current level words findDict2(*it,dict,next_lev); } if (next_lev.empty()){return res;} if (next_lev.find(end)!=dict.end()){ //if find end string output(start,end); return res; } cur_lev.clear(); cur_lev = next_lev; next_lev.clear(); } return res; }