给定两个单词(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” 不在字典中,所以不存在符合要求的转换序列。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-ladder-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:BFS
class Solution {
public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
List<List<String>> ans=new ArrayList<List<String>>();//存答案
List<List<Integer>> mp=new ArrayList<List<Integer>>();//存图
List<List<Integer>> pre=new ArrayList<List<Integer>>();//存前驱
int end=-1;//找endWord的位置
for(int i=0;i<wordList.size();i++){
if(wordList.get(i).equals(endWord)){
end=i;
break;
}
}
if(end==-1) return ans;
for(int i=0;i<wordList.size()+1;i++){
mp.add(new LinkedList<Integer>());
pre.add(new ArrayList<Integer>());
}
for(int i=0;i<wordList.size();i++){//单词表内建图
for(int j=i+1;j<wordList.size();j++){
if(judge(wordList,i,j)){
mp.get(i).add(j);
mp.get(j).add(i);
}
}
}
wordList.add(beginWord);//起点建图
int begin=wordList.size()-1;
for(int i=0;i<wordList.size()-1;i++){
if(judge(wordList,begin,i)){
mp.get(begin).add(i);
}
}
int[] step=new int[wordList.size()];
Queue<Integer> q=new LinkedList<Integer>();
q.offer(begin);
step[begin]=1;
while(!q.isEmpty()){
int u=q.poll();
if(u==end){
solve(end,begin,new LinkedList<String>(),pre,wordList,ans);
break;
}
for(int i=0;i<mp.get(u).size();i++){
int v=mp.get(u).get(i);
if(step[v]==0){
pre.get(v).add(u);
q.offer(v);
step[v]=step[u]+1;
}
else if(step[v]==step[u]+1){
pre.get(v).add(u);
}
}
}
return ans;
}
public boolean judge(List<String> wordList,int a,int b){
String sa=wordList.get(a);
String sb=wordList.get(b);
int cnt=0;
for(int i=0;i<sa.length();i++){
if(sa.charAt(i)!=sb.charAt(i)){
cnt++;
if(cnt>1) return false;
}
}
return true;
}
public void solve(int now,int begin,LinkedList<String> road,List<List<Integer>> pre,List<String> wordList,List<List<String>> ans){
road.addFirst(wordList.get(now));
if(now==begin){
ans.add(new LinkedList<String>(road));
road.removeFirst();
return ;
}
for(int i=0;i<pre.get(now).size();i++){
int to=pre.get(now).get(i);
solve(to,begin,road,pre,wordList,ans);
}
road.removeFirst();
return ;
}
}