题目:
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:
- Only one letter can be changed at a time
- Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
For example,
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]
Return
[ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ]
Note:
- Return an empty list if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
- You may assume no duplicates in the word list.
- You may assume beginWord and endWord are non-empty and are not the same.
思路:
由于需要返回各种可能的路径,所以我们需要为每一个节点记录其父节点,这样我们最后就可以从终点开始一个个往前找其父节点,直到找到起始点,然后翻转一下加入结果集合即可。由于在不同的路径中,可能会包含同一个节点,所以单纯依靠原来的unordered_set是不够的。为此,我们额外定义一个unordered_map,记录一个节点的所有父节点所构成的集合。
有了上述的unordered_map这样的数据结构,我们的思路就是:首先采用广度优先搜索策略建立起来各个节点之间的邻接关系(也就是通过修改一个字母可以变成另一个字母的情况);然后通过深度优先策略找出所有符合条件的路径。
不得不说,这道题目还是比较变态的。
代码:
class Solution {
public:
vector<vector<string>> findLadders(string beginWord, string endWord, unordered_set<string> &wordList) {
wordList.insert(endWord);
wordList.erase(beginWord);
que.push(make_pair(beginWord, 1));
while(!que.empty()) {
auto val = que.front();
que.pop();
for(int i = 0; i < val.first.size(); i++) {
string tem = val.first;
for(int j =0; j < 26; j ++) {
tem[i] = 'a' + j;
if(wordList.count(tem)) {
que.push(make_pair(tem, val.second+1));
wordList.erase(tem);
hash[tem].insert(val);
}
else if(hash.count(tem)&&hash[tem].begin()->second==val.second) {
hash[tem].insert(val);
}
}
}
}
DFS(hash[endWord], vector<string>{endWord});
return result;
}
private:
void DFS(set<pair<string, int>> st, vector<string> vec) {
for(auto val: st) {
vec.push_back(val.first);
if(hash.count(val.first)==0) {
reverse(vec.begin(), vec.end());
return result.push_back(vec);
}
DFS(hash[val.first], vec);
vec.pop_back();
}
}
vector<vector<string>> result;
unordered_map<string, set<pair<string, int>>> hash;
queue<pair<string, int>> que;
};