给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列。转换需遵循如下规则:
- 每次转换只能改变一个字母。
- 转换过程中的中间单词必须是字典中的单词。
说明:
- 如果不存在这样的转换序列,返回一个空列表。
- 所有单词具有相同的长度。
- 所有单词只由小写字母组成。
- 字典中不存在重复的单词。
- 你可以假设 beginWord 和 endWord 是非空的,且二者不相同。
示例 1:
输入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]
输出:
[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]
示例 2:
输入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
输出: []
解释: endWord "cog" 不在字典中,所以不存在符合要求的转换序列。
class Solution {
public:
struct Qitem{
string node;
int parent_pos;
int step;
Qitem(string node,int parent_pos,int step):
node(node),parent_pos(parent_pos),step(step){
}
};
bool calnotsame(string &beginWord, string &endWord){
int cnt=0;
for(int i=0;i<beginWord.length();i++){
if(beginWord[i]!=endWord[i]){
cnt++;
}
}
return cnt==1;//只有一个字符相同才能转换,才有效
}
void makegraph(string &beginWord, vector<string>& wordList,map<string,vector<string>>&graph){
int has_been_word=0;
for(int i=0;i<wordList.size();i++){
if(wordList[i]==beginWord){
has_been_word=1;
}
graph[wordList[i]]=vector<string>();//初始化临接表
}
for(int i=0;i<wordList.size();i++){
for(int j=i+1;j<wordList.size();j++){
if(calnotsame(wordList[i],wordList[j])){
graph[wordList[i]].push_back(wordList[j]);//互相都能访问,双向存储
graph[wordList[j]].push_back(wordList[i]);
}
}
if(has_been_word==0&&calnotsame(beginWord,wordList[i])){
graph[beginWord].push_back(wordList[i]);
}
}
}
void BFS(string beginWord, string endWord, vector<string>& wordList,map<string,vector<string>>&graph,vector<Qitem>&Q,vector<int>&end_word_pos){
map<string,int>visit;
int min=0;
int front=0;
visit[beginWord]=1;
Q.push_back(Qitem(beginWord.c_str(),-1,1));
while(front!=Q.size()){
const string &node=Q[front].node;
int step=Q[front].step;
if(min!=0&&step>min)
break;
if(node==endWord){
min=step;
end_word_pos.push_back(front);
}
const vector<string>&neighbors=graph[node];
for(int i=0;i<neighbors.size();i++){
if(visit.find(neighbors[i])==visit.end()||visit[neighbors[i]]==step+1){//如果临接这个string没被搜索过
Q.push_back(Qitem(neighbors[i],front,step+1));//加进队列
visit[neighbors[i]]=step+1;//加进visit
}
}
front++;
}
}
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
map<string,vector<string>>graph;
makegraph(beginWord, wordList,graph);
vector<Qitem>Q;
vector<int>end_word_pos;
BFS(beginWord, endWord, wordList,graph,Q,end_word_pos);
vector<vector<string>>result;
for(int i=0;i<end_word_pos.size();i++){
int pos=end_word_pos[i];
vector<string>path;
while(pos!=-1){
path.push_back(Q[pos].node);
pos=Q[pos].parent_pos;
}
result.push_back(vector<string>());
for(int j=path.size()-1;j>=0;j--){
result[i].push_back(path[j]);
}
}
return result;
}
};