首页 > 代码库 > leetcode: Word Ladder II
leetcode: 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"] ]
本题5星难度,和I一样用bfs,但是因为要输出,所以时间不够
先遍历找到每个词的前驱词,用两个队列保存当前层和之前层的词,一个是正在处理,一个是下次需要处理
得到前驱词表后,从end往前递归打印路径
AC代码
class Solution { public: vector< vector< string> > res; vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) { dict.insert(start); dict.insert(end); unordered_map< string, vector< string> > precursor;//保存每个词对应的前驱词 for( unordered_set< string>::const_iterator citer = dict.begin(); citer != dict.end(); ++citer)//初始化 precursor.insert( make_pair( *citer, vector< string>())); vector< unordered_set< string> >layers(2);//分别用来保存当前层的词和之前层的词 layers[0].insert(start); int cur = 0; int pre = 1; while(true){ cur = !cur;//两层互换 pre = !pre; for( unordered_set< string>::const_iterator citer = layers[pre].begin(); citer != layers[pre].end(); ++citer) dict.erase(*citer);//删除之前层里出现在字典里的词 layers[cur].clear(); //bfs搜索之前层里每个词通过一次变换可以达到的词,该词如果在字典里就放入当前层 for( unordered_set< string>::const_iterator citer = layers[pre].begin(); citer != layers[pre].end(); ++citer){ string str = *citer; for( int i = 0; i < str.size(); ++i){ for( int j = 'a'; j <= 'z'; ++j){ if( str[i] == j) continue; string tmp = str; tmp[i] = j; if( dict.count(tmp)){ precursor[tmp].push_back(str); layers[cur].insert(tmp); } } } } if( layers[cur].empty())//如果当前层空,说明无法从start到end,结束 return res; if( layers[cur].count(end))//如果当前层出现end,说明已经找到了转换,而且因为是根据层数来的,所以都是shortest break; } vector< string> path; generatePath( precursor, path, end); return res; } //从end开始从后往前递归 void generatePath( unordered_map< string, vector< string> > &precursor, vector< string> &path, string end){ if( precursor[end].size() == 0){//没有前驱词说明已经到了start path.push_back(end); vector< string> tmp = path; reverse( tmp.begin(), tmp.end());//反转次序 res.push_back(tmp); path.pop_back(); } path.push_back(end); for( vector< string>::const_iterator citer = precursor[end].begin(); citer != precursor[end].end(); ++citer){ generatePath( precursor, path, *citer); } path.pop_back(); } };
TLE得一塌糊涂,还是不能用递归的
class Solution { public: vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) { vector< vector< string> > res; vector< string> cur; cur.push_back(start); dict.insert(end); unordered_set< string> tmp = dict; int length = ladderLength(start, end, tmp); core( res, cur, start, end, dict, length); return res; } void core( vector< vector< string> > &res, vector< string> &cur, string start, string end, unordered_set< string> &dict, int l){ if( cur.size() > l) return; if( start == end){ res.push_back(cur); return; } for( int i = 0; i < start.size(); ++i){ for( int j = 'a'; j <= 'z'; ++j){ if( start[i] == j) continue; else{ string tmp = start; tmp[i] = j; if( dict.count(tmp)){ cur.push_back(tmp); dict.erase(tmp); core( res, cur, tmp, end, dict, l); cur.pop_back(); dict.insert(tmp); } } } } } int ladderLength(string start, string end, unordered_set<string> &dict) { int shortest = INT_MAX; dict.insert(end); queue< pair< string, int> > q; q.push( pair< string, int>( start, 1)); while( !q.empty()){ pair< string, int> cur = q.front(); q.pop(); if( cur.first == end){ shortest = shortest < cur.second ? shortest : cur.second; continue; } string str = cur.first; for( int i = 0; i < str.size(); ++i){ for( int j = 'a'; j <= 'z'; ++j){ if( str[i] == j) continue; string tmp = str; tmp[i] = j; if( dict.count(tmp)){ q.push( make_pair( tmp, cur.second+1)); dict.erase(tmp); } } } } if( shortest == INT_MAX) return 0; return shortest; } };
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。