题目如下:
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 >& buildTree (
string& start,
string& end,
unordered_set &dict) {
static map< string, unordered_set > parents;
parents.clear();
unordered_set level[3];
unordered_set *previousLevel = &level[0];
unordered_set *currentLevel = &level[1];
unordered_set *newLevel = &level[2];
unordered_set *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; isize(); 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 > &parents,
// vector path,
vector &path, //减少内存使用,发挥DFS优势。
vector< vector > &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 > findLadders(
string start,
string end,
unordered_set &dict) {
vector< vector > ladders;
vector ladder;
ladder.push_back(start);
if (start == end){
ladder.push_back(end);
ladders.push_back(ladder);
return ladders;
}
map< string, unordered_set >& 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