题目链接: https://leetcode.com/problems/word-ladder-ii/
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord toendWord, such that:
For example,
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
Return
[ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ]
Note:
大概过程差不多, 但是有点不同的是当我们将字典中的一个字符串删除的时候在另一条路径上可能还会用到这个字符. 也就是像这样:
A -> C -> D, B->C->D
他们都会经过C, 并且两个都是最短的路径, 在A的时候搜索到C, 并且将C从字典中删除, 当B在搜索与其距离为1的字符串时, C已经不在字典中了, 那么怎么办呢? 我们设置一个hash表用来存储一个字符串的父结点集合, 这样C不在字典中再去查hash表看C是否在hash表中, 如果在的话并且C的父结点层次和B一样, 那么就将B也加入到C的父结点结合中去. 可以知道, 一个字符串的父结点集合的距离起点的距离必然是相等的, 也就是说他们都是最短距离.
最后遍历完所有的点之后, 再用DFS从终点往前找出所有集合即可.
代码如下:
class Solution { public: void DFS(set<pair<string, int>> st, vector<string> vec) { for(auto val: st) { vec.push_back(val.first); if(hash.find(val.first) == hash.end()) { reverse(vec.begin(), vec.end()); result.push_back(vec); } else DFS(hash[val.first], vec); vec.pop_back(); } } vector<vector<string>> findLadders(string beginWord, string endWord, unordered_set<string> &wordList) { wordList.insert(endWord); que.push(make_pair(beginWord, 1)); wordList.erase(beginWord); while(!que.empty()) { auto val = que.front(); que.pop(); for(int i = 0; i < val.first.size(); i++) { string str = val.first; for(int j =0; j< 26; j++) { str[i] = 'a' + j; if(wordList.count(str) == 1) { que.push(make_pair(str, val.second+1)); wordList.erase(str); hash[str].insert(val); } else if(hash.find(str)!=hash.end() && val.second==(*hash[str].begin()).second) hash[str].insert(val); } } } vector<string> vec; vec.push_back(endWord); DFS(hash[endWord], vec); return result; } private: queue<pair<string, int>> que; vector<vector<string>> result; unordered_map<string, set<pair<string, int>>> hash; };