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
All words have the same length.
All words contain only lowercase alphabetic characters.
分析:
这题目和ladder I的区别在于,不需要记录步数,而是需要枚举所有可能的path,具体思路如下:
1. bfs获取邻接表,同时还要开另外一个hash记录每一个点的stepcount
2. dfs从后往前做,每次dfs加入end,然后用上一步的end继续递归,注意条件是stepcount减少1
值得注意的地方包括:
因为需要一个完整的图来做这个,所以要把start和end放到字典里面
两个hash要提前开好,虽然都没有差,但是最好对他们进行初始化
这是一道综合训练的大题目,100行代码,并不容易写,需要重复练习。
解法:
class Solution {
public:
/**
* @param start, a string
* @param end, a string
* @param dict, a set of string
* @return a list of lists of string
*/
void dfs(string start,
string end,
unordered_map<string, vector<string> > &map,
unordered_map<string, int> &distance,
vector<string> path,
vector<vector<string> > &res) {
// important, dfs is from end to start
path.push_back(end);
if (end == start) {
reverse(path.begin(), path.end() );
res.push_back(path);
reverse(path.begin(), path.end() );
return;
}
vector<string> temp = map[end];
for (int i = 0; i < temp.size(); i++) {
if(distance[temp[i] ] == distance[end] - 1) {
dfs(start, temp[i], map, distance, path, res);
}
}
}
void bfs(string start,
string end,
unordered_set<string> &dict,
unordered_map<string, vector<string> > &map,
unordered_map<string, int> &distance) {
queue<string> Q;
Q.push(start);
while (!Q.empty() ) {
string word = Q.front();
Q.pop();
// get the next visit list
vector<string> nextList;
for (int j = 0; j < word.size(); j++) {
char oldChar = word[j];
for (char c = 'a'; c < 'z'; c++) {
if (c == oldChar) {
continue;
}
word[j] = c;
if (dict.find(word) != dict.end() ) {
nextList.push_back(word);
}
}
word[j] = oldChar;
}
map[word] = nextList;
// avoid revisiting and count distance
for (int i = 0; i < nextList.size(); i++) {
if (distance.find(nextList[i]) == distance.end() ) {
distance[nextList[i] ] = distance[word] + 1;
Q.push(nextList[i]);
}
}
// to safe time
if (word == end) {
break;
}
}
}
vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
// write your code here
vector<vector<string> > res;
if (start.size() == 0 || end.size() == 0 || dict.size() == 0) {
return res;
}
if (start == end) {
vector<string> temp;
temp.push_back(start);
res.push_back(temp);
return res;
}
// important
dict.insert(start);
dict.insert(end);
unordered_map<string, vector<string> > map;
unordered_map<string, int> distance;
bfs(start, end, dict, map, distance);
vector<string> path;
dfs(start, end, map, distance, path, res);
return res;
}
};