- 题目描述
给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从
beginWord 到 endWord 的最短转换序列。转换需遵循如下规则:
每次转换只能改变一个字母。
转换后得到的单词必须是字典中的单词。
说明:
如果不存在这样的转换序列,返回一个空列表。
所有单词具有相同的长度。
所有单词只由小写字母组成。
字典中不存在重复的单词。
你可以假设 beginWord 和 endWord 是非空的,且二者不相同。
- 题解
广度优先搜索
- 代码
class Solution {
public:
void dfs(vector<vector<string>> &res,vector<string> tmp,unordered_map<string,vector<string>>& next,string beginWord, string endWord){
if (beginWord==endWord){
res.push_back(tmp);
return ;
}
for (int i=0;i<next[beginWord].size();i++){
tmp.push_back(next[beginWord][i]);
dfs(res,tmp,next,next[beginWord][i],endWord);
tmp.pop_back();
}
}
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
int length=wordList.size();
if (!length) return vector<vector<string>>{};
unordered_map<string,bool> visited;
unordered_set<string> myset;
int n=beginWord.size();
for (int i=0;i<wordList.size();i++) {
visited[wordList[i]]=false;
myset.insert(wordList[i]);
}
queue<string> que;
que.push(beginWord);
visited[beginWord]=true;
unordered_map<string,vector<string>> next;
unordered_map<string,bool> inque;
inque[beginWord]=true;
vector<string> vec;
bool f=false;
while (!que.empty()){
int cnt=que.size();
while (cnt--){
string t=que.front(),k;
que.pop();
vec.push_back(t);
for (int i=0;i<n;i++){
k=t;
for (int j=0;j<26;j++){
k[i]=j+'a';
if (myset.find(k)!=myset.end()){
if (k==endWord){
next[t].push_back(k);
f=true;
}else if (!visited[k]){
if (!inque[k]) {
que.push(k);
inque[k]=true;
}
next[t].push_back(k);
}
}
}
}
}
for (int i=0;i<vec.size();i++){
for (int j=0;j<next[vec[i]].size();j++) visited[next[vec[i]][j]]=true;
}
vec.clear();
if (f) break;
}
vector<vector<string>> res;
if (f){
vector<string> tmp={beginWord};
dfs(res,tmp,next,beginWord,endWord);
}
return res;
}
};