【LeetCode题解】127. 单词接龙

目录

version1:深度递归回溯超时

version2:不递归回溯如何遍历所有可能结果?层次遍历


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

每次转换只能改变一个字母。
转换过程中的中间单词必须是字典中的单词。
说明:如果不存在这样的转换序列,返回 0。所有单词具有相同的长度。所有单词只由小写字母组成。字典中不存在重复的单词。
你可以假设 beginWord 和 endWord 是非空的,且二者不相同。
示例 1:输入:
beginWord = "hit",endWord = "cog",wordList = ["hot","dot","dog","lot","log","cog"]

输出: 5解释: 一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",
     返回它的长度 5。
示例 2:输入:
beginWord = "hit"endWord = "cog"wordList = ["hot","dot","dog","lot","log"]

输出: 0解释: endWord "cog" 不在字典中,所以无法进行转换。

version1:深度递归回溯超时

1、对List中每个元素判断是否能与beginWord一步转换,如果可以,则递归进行判断List中每个元素判断是否能与List.get(i)一步转换,如无法转换则回溯

2、isUsed数组标记以及加入转换的元素,避免反复转换,即hit-->hot-->hit-->hot .....

3、效率太低,在第一步的时候大量尝试无法形成转换的错误序列并尝试递归(能否反向endWord到beginWord?效率会否不同,感觉应该差不多)

class Solution {
    int ret = Integer.MAX_VALUE;
    public int ladderLength(String beginWord, String endWord, List wordList) {
        if(wordList.size()==0 || wordList.indexOf(endWord)==-1){
            return 0;
        }        
        boolean[] isUsed = new boolean[wordList.size()];
        //最短为1
        permutation(beginWord,endWord,wordList,1,isUsed);
        if(ret == Integer.MAX_VALUE){
            return 0;
        }else{
            return ret;
        }
    }
    
    void permutation(String s, String target, List wordList,int step,boolean[] isUsed){
        // System.out.println(s);
        //isUsed标记当前为是否被使用过,避免重复接龙 a-b-a-b...
        if(s.equals(target)){
            ret = step

version2:不递归回溯如何遍历所有可能结果?层次遍历

1、我的想法是递推关系:建立递推关系:从endWord逆推给List中每个元素建立一个可到达最短的步数索引如:endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"],则 step为 [ len,len,2,len,2,1],从两个step=2的为剩余3个建立索引...

2、实现的过程类似二叉树的层次遍历,索引使用Queue allSteps分层遍历,使用visited数组对以及逆推建立过联系的元素不再重复访问,因为可能会赋值更长的路径以及出现环

class Solution {
    public int ladderLength(String beginWord, String endWord, List wordList) {
        //建立递推关系:从endWord逆推给List中每个元素建立一个可到达最短的步数索引如:endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"],则 step为 [ len,len,2,len,2,1],从两个step=2的为剩余3个建立索引...
        int index= wordList.indexOf(endWord);
        if(wordList.size()==0 || index==-1){
            return 0;
        }
        //提前判断是否能一步转换,否则会出现 "a","c",["a","b","c"],检测到b时发现b可以一步转为c导致非最短路劲
        if(canTurnTo(beginWord,endWord)){
            return 2;
        }
        //是否访问过
        boolean[] visited = new boolean[wordList.size()];
        Arrays.fill(visited,false);
        visited[index] = true;
        //当前N步能到达队列
        Queue allSteps = new LinkedList<>();
        allSteps.offer(endWord);
        //当前处理步数索引
        index = 1;
        //Map:key = string ,val = string到达endWord的步数
        Map m = new HashMap<>();
        m.put(endWord,index);
        
        while(!allSteps.isEmpty()){
            //取当前步数相同层的长度
            int len = allSteps.size();
            while(len-->0){
                String str = allSteps.poll();
                index = m.get(str);
                for(int j=0 ; j

 

 

你可能感兴趣的:(LeetCode题解)