题目如下:
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
分析如下:
这道题目真心很难通过。
1 考虑保存father信息来记录每个节点的前驱。
2 可是,最优路径可能在某个节点重叠。这样一个节点就不止一个father。
3 如果考虑用一个list或者vector保存当前节点的前驱,那么可能会Memory Limit Exceed
4 haoel大牛的做法是BFS + DFS.
// For example: // // start = "hit" // end = "cog" // dict = ["hot","dot","dog","lot","log","dit","hig", "dig"] // // +-----+ // +-------------+ hit +--------------+ // | +--+--+ | // | | | // +--v--+ +--v--+ +--v--+ // | dit | +-----+ hot +---+ | hig | // +--+--+ | +-----+ | +--+--+ // | | | | // | +--v--+ +--v--+ +--v--+ // +----> dot | | lot | | dig | // +--+--+ +--+--+ +--+--+ // | | | // +--v--+ +--v--+ | // +----> dog | | log | | // | +--+--+ +--+--+ | // | | | | // | | +--v--+ | | // | +--->| cog |<-- + | // | +-----+ | // | | // | | // +----------------------------------+
haoel大牛的代码:
// 654ms class Solution { public: map< string, unordered_set<string> >& buildTree ( string& start, string& end, unordered_set<string> &dict) { static map< string, unordered_set<string> > parents; parents.clear(); unordered_set<string> level[3]; unordered_set<string> *previousLevel = &level[0]; unordered_set<string> *currentLevel = &level[1]; unordered_set<string> *newLevel = &level[2]; unordered_set<string> *p =NULL; currentLevel->insert(start); bool reachEnd = false; while( !reachEnd ) { newLevel->clear(); for(auto it=currentLevel->begin(); it!=currentLevel->end(); it++) { for (int i=0; i<it->size(); i++) { string newWord = *it; for(char c='a'; c<='z'; c++){ newWord[i] = c; if (newWord == end){ reachEnd = true; parents[*it].insert(end); continue; } if ( dict.count(newWord)==0 || currentLevel->count(newWord)>0 || previousLevel->count(newWord)>0 ) { continue; } newLevel->insert(newWord); //parents[newWord].insert(*it); parents[*it].insert(newWord); } } } if (newLevel->empty()) break; p = previousLevel; previousLevel = currentLevel; currentLevel = newLevel; newLevel = p; } if ( !reachEnd ) { parents.clear(); } return parents; } void generatePath(string start, string end, map< string, unordered_set<string> > &parents, // vector<string> path, vector<string> &path, //减少内存使用,发挥DFS优势。 vector< vector<string> > &paths) { if (parents.find(start) == parents.end()){ if (start == end){ paths.push_back(path); } return; } for(auto it=parents[start].begin(); it!=parents[start].end(); it++){ path.push_back(*it); generatePath(*it, end, parents, path, paths); path.pop_back(); } } vector< vector<string> > findLadders( string start, string end, unordered_set<string> &dict) { vector< vector<string> > ladders; vector<string> ladder; ladder.push_back(start); if (start == end){ ladder.push_back(end); ladders.push_back(ladder); return ladders; } map< string, unordered_set<string> >& parents = buildTree(start, end, dict); if (parents.size()<=0) { return ladders; } generatePath(start, end, parents, ladder, ladders); return ladders; } };
参考链接:
1. https://github.com/haoel/leetcode/blob/master/algorithms/wordLadder/wordLadder.II.cpp