• Leetcode 126.单词接龙II


    单词接龙II

    给定两个单词(beginWordendWord)和一个字典 wordList,找出所有从 beginWord endWord 的最短转换序列。转换需遵循如下规则:

    1. 每次转换只能改变一个字母。
    2. 转换过程中的中间单词必须是字典中的单词。

    说明:

    • 如果不存在这样的转换序列,返回一个空列表。
    • 所有单词具有相同的长度。
    • 所有单词只由小写字母组成。
    • 字典中不存在重复的单词。
    • 你可以假设 beginWordendWord 是非空的,且二者不相同。

    示例 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" 不在字典中,所以不存在符合要求的转换序列。

    先BFS遍历图,找到所有到达结尾单词的最短路径,同时记录图。最后再DFS遍历图。

    BFS遍历图:queue用来BFS遍历图。队列按结点的深度依次存放待处理的结点。首先存放第一层结点,弹出,根据第一层结点找到所有第二层结点放入队列;弹出第二层某个结点,根据此结点找到所有第三层结点放入队列,以此类推。

    记录图:记录图中每个结点的父节点们。记录图中结点的层数(深度)。

    DFS遍历记录的图得出结果。

     1 class Solution{
     2     public boolean isDiffOneWord(String a,String b){
     3         int diffnum=0;
     4         for(int i=0;i<a.length();i++){
     5             if(a.charAt(i)!=b.charAt(i)){
     6                 diffnum++;
     7             }
     8             if(diffnum==2){
     9                 return false;
    10             }
    11         }
    12         if(diffnum==1){
    13             return true;
    14         }
    15         return false;
    16     }
    17 
    18     public List<List<String>> findLadders(String beginWord,String endWord,List<String> wordList){
    19         List<List<String>> res=new ArrayList<List<String>>();
    20         int endIndex=wordList.indexOf(endWord);
    21         if(endIndex==-1){
    22             return res;
    23         }
    24         int beginIndex=wordList.indexOf(beginWord);
    25         //若beginWord不在wordList中,则添加至wordList末尾
    26         if(beginIndex==-1){
    27             wordList.add(beginWord);
    28             beginIndex=wordList.size()-1;
    29         }
    30         //queue用来BFS遍历图。队列按节点的深度依次存放待处理的节点。首先存放第一层结点,弹出
    31         //根据第一层结点找到所有第二层结点放入队列;以此类推
    32         Queue<Integer> queue=new LinkedList<Integer>();
    33         queue.offer(beginIndex);
    34         //fatherNodes、height用来记录图
    35         //记录图中每个节点的父亲节点们
    36         Map<Integer,List<Integer>> fatherNodes=new HashMap<Integer,List<Integer>>();
    37         for(int i=0;i<wordList.size();i++){
    38             fatherNodes.put(i,new ArrayList<Integer>());
    39         }
    40         //记录图中节点的层数(深度)
    41         int[] height=new int[wordList.size()];
    42         height[beginIndex]=1;
    43         while(!queue.isEmpty()){
    44             int nowIndex=queue.poll();
    45             //若最短深度的路径已经记录完毕,退出循环
    46             //height[nowIndex]>=height[endIndex]针对多个父亲点的情况
    47             if(height[endIndex]!=0 && height[nowIndex]>=height[endIndex]){
    48                 break;
    49             }
    50             for(int i=0;i<wordList.size();i++){
    51                 //height[i]==0未访问过的节点,height[i]=height[nowIndex]+1多个父亲节点的情况,且一个父亲节点已经访问过该结点
    52                 if((height[i]==0 || height[i]==height[nowIndex]+1) && isDiffOneWord(wordList.get(nowIndex),wordList.get(i))){
    53                     if(height[i]==0){
    54                         queue.offer(i);
    55                         height[i]=height[nowIndex]+1;
    56                         fatherNodes.get(i).add(nowIndex);
    57                     }else{
    58                         //height[i]=height[nowIndex]+1多个父亲节点的情况,且一个父亲节点已经访问过该结点
    59                         fatherNodes.get(i).add(nowIndex);
    60                     }
    61                 }
    62             }
    63         }
    64 
    65         if(height[endIndex]==0){
    66             return res;
    67         }else{
    68             List<String> list=new ArrayList<String>();
    69             list.add(wordList.get(endIndex));
    70             dfs(endIndex,list,res,wordList,fatherNodes,beginIndex);
    71         }
    72         return res;
    73     }
    74 
    75     public void dfs(int lastIndex,List<String> list,List<List<String>> res,List<String> wordList,Map<Integer,List<Integer>> fatherNodes,int beginIndex){
    76         if(lastIndex==beginIndex){
    77             List<String> newList=new ArrayList<String>(list);
    78             Collections.reverse(newList);
    79             res.add(newList);
    80             return;
    81         }
    82         for(int i=0;i<fatherNodes.get(lastIndex).size();i++){
    83             int fatherIndex=fatherNodes.get(lastIndex).get(i);
    84             list.add(wordList.get(fatherIndex));
    85             dfs(fatherIndex,list,res,wordList,fatherNodes,beginIndex);
    86             list.remove(list.size()-1);
    87         }
    88     }
    89 }
  • 相关阅读:
    从头到尾测地理解KMP算法【转】
    【Android】使用BaseAdapter实现复杂的ListView【转】
    Git命令速查表【转】
    图解Git命令【转】
    Git-入门教程
    自定义Git【转】
    linux命令大全
    ppt转pdf网址
    【转】设置电脑眼睛保护色(背景色)
    【转】putty基本操作--不错
  • 原文地址:https://www.cnblogs.com/kexinxin/p/10187795.html
Copyright © 2020-2023  润新知