题解:
具体的思路是,分别从起始和结束字符串出发两遍BFS, 得到每个点到起始字符串的最短距离和终点字符串的最短距离。
然后再从起始字符串出发,DFS 寻找路径。由于已经通过BFS得到每个点到两端的最短距离,所以DFS寻找路径可以很大程度的剪枝,从而防止了超时。
AC 代码(c++):
struct Node
{
string word;
int dis;
Node(){}
Node(string word,int dis)
{
this->word = word;
this->dis = dis;
}
};
class Solution {
public:
int disBegin[100005];
int disEnd[100005];
int vis[100005];
int vis2[100005];
queue<Node> q;
vector<vector<string>> res;
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
q.push(Node(beginWord,0));
int l = wordList.size();
int tag=0;
memset(vis,0,sizeof(vis));
memset(vis2,0,sizeof(vis2));
memset(disBegin,-1,sizeof(disBegin));
memset(disEnd,-1,sizeof(disEnd));
for(int i=0;i<l;i++)
{
if(endWord==wordList[i])
{
disEnd[i]=0;
vis2[i] =1;
tag=1;
}
if(beginWord == wordList[i])
{
disBegin[i] = 0;
vis[i]=1;
}
}
if(tag==0)
return res;
while(!q.empty())
{
Node term = q.front();
q.pop();
for(int i=0;i<l;i++)
{
if(change(term.word,wordList[i]))
{
if(vis[i]==0)
{
vis[i]=1;
q.push(Node(wordList[i],term.dis+1));
disBegin[i] = term.dis+1;
}
}
}
}
q.push(Node(endWord,0));
while(!q.empty())
{
Node term = q.front();
q.pop();
for(int i=0;i<l;i++)
{
if(change(term.word,wordList[i]))
{
if(vis2[i]==0)
{
vis2[i]=1;
q.push(Node(wordList[i],term.dis+1));
disEnd[i] = term.dis+1;
}
}
}
}
vector<string> ans;
ans.push_back(beginWord);
dfs(beginWord,ans,wordList,endWord,1);
return res;
}
void dfs(string word,vector<string> ans,vector<string> wordList,string endWord,int tag)
{
if(word == endWord)
{
res.push_back(ans);
return;
}
int mm = 9999999;
for(int i=0;i<wordList.size();i++)
{
if(disBegin[i]==tag && disEnd[i]!=-1)
{
mm = min(mm,disEnd[i]);
}
}
for(int i=0;i<wordList.size();i++)
{
if(disBegin[i]==tag)
{
if(disEnd[i] == mm)
{
if(change(word,wordList[i]))
{
ans.push_back(wordList[i]);
dfs(wordList[i],ans,wordList,endWord,tag+1);
ans.pop_back();
}
}
}
}
}
bool change(string a ,string b)
{
int num = 0;
int l = a.length();
for(int i=0;i<l;i++)
{
if(a[i]!=b[i])
num++;
}
if(num==1)
return true;
else
return false;
}
};