126. 单词接龙 II

给定两个单词(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 ;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值