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.
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.
Example 1:
Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"] Output: [ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ]
Example 2:
Input: beginWord = "hit" endWord = "cog" wordList = ["hot","dot","dog","lot","log"] Output: [] Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.
题解:难题,主要用bfs保证达到的路径最短然后用dfs求出路径,首先把问题转化成一个空间树或者一个图,然后用bfs的方法一层一层访问,注意bfs在没有权值时所求路径是最短的,然后为了避免访问过程重新访问这里重新访问是a到b又访问b到a的循环需要设置一个set记录未访问点,然后在把每层节点都访问结束后删掉访问点,这里没有用队列而是用两个set来完成一层一层的遍历,cur表示当前层,net表示下一层,这样便于通过遍历net来删除访问点,每次加入路径后构造这个树,为了优化这个树从end开始访问到start所以加入时须注意,bfs结束后我们得到了这个搜索树只需通过dfs来记录路径即可
class Solution {
public:
void dfs(unordered_map<string,unordered_set<string>> path,string st,string ed,vector<string>& tmp,vector<vector<string>>& res){
tmp.push_back(st);
if(st==ed){
vector<string> npath=tmp;
reverse(npath.begin(),npath.end());
res.push_back(npath);
return ;
}
for(string ss:path[st]){
dfs(path,ss,ed,tmp,res);
tmp.pop_back();
}
}
vector<vector<string>> findLadders(string beginWord, string endWord,vector<string> &wordList)
{
unordered_set<string> dict(wordList.begin(),wordList.end());
unordered_map<string,unordered_set<string>> path;
unordered_set<string> unvisited=dict;
vector<string> tmp;
vector<vector<string>> res;
if(dict.count(beginWord)) unvisited.erase(beginWord);
unordered_set<string> cur;
cur.insert(beginWord);
unordered_set<string> net;
while(cur.count(endWord)==0&&!unvisited.empty()){
for(string s:cur){
for(int i=0;i<s.size();i++)
for(char c='a';c<='z';c++){
string tmp=s;
tmp[i]=c;
if(tmp==s) continue;
if(unvisited.count(tmp)){
path[tmp].insert(s);
net.insert(tmp);
}
}
}
if(net.empty()) break;
for(string ss:net){
unvisited.erase(ss);
}
cur=net;
net.clear();
}
if(cur.count(endWord)){
dfs(path,endWord,beginWord,tmp,res);
}
return res;
}
};