Java剑指 Offer II 108. 单词演变(击败93.27%用户)

题目:

在字典(单词列表) wordList 中,从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列:

序列中第一个单词是 beginWord 。
序列中最后一个单词是 endWord 。
每次转换只能改变一个字母。
转换过程中的中间单词必须是字典 wordList 中的单词。
给定两个长度相同但内容不同的单词 beginWord 和 endWord 和一个字典 wordList ,找到从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0。

示例 :

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



思路:

双向广度优先搜索,

代码长的话就一部分一部分写功能,慢慢优化,会好起来的

复杂度:

时间:单循环O( n )。

空间:O( n )。

代码:

 public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        //将字典先放入set
        Set<String> notVisited = new HashSet<>(wordList);
        //字典里没有结束词时,直接返回0
        if(!notVisited.contains(endWord)) return 0;

        Set<String> set1 = new HashSet<>();
        Set<String> set2 = new HashSet<>();
        int length =2;
        set1.add(beginWord);
        set2.add(endWord);
        //被set2添加了
        notVisited.remove(endWord);
        while(!set1.isEmpty() && !set2.isEmpty()){
            //为了保证双向广度优先的进行,哪个少就找哪个的节点
            if(set2.size() < set1.size()){
                Set<String> temp = set1;
                set1 = set2;
                set2 = temp;
            }
            //set3存放与当前访问的节点相邻的节点
            Set<String> set3 = new HashSet<>();
            //对set1中节点访问
            for(String word: set1){
                //一个单词修改一个字母可以演变出的所有单词
                List<String> neighbors = getNeighbors(word);
                for(String neighbor:neighbors){
                    //如果set2有其中一个,就可以返回长度了
                    if(set2.contains(neighbor)) return length;
                    //如果在未访问列表里就加到set3当中,未访问列表移除
                    if(notVisited.contains(neighbor)){
                    set3.add(neighbor);
                    notVisited.remove(neighbor);
                }
            }  
        }
          //长度加一,并且将set3赋给set1
            length++;
            set1 = set3; 
      }
        return 0; 
    }
    //一个单词修改一个字母可以演变出的所有单词
    private List<String> getNeighbors(String word){
        List<String> neighbors = new LinkedList<>();
        char[] chars = word.toCharArray();
        for(int i =0;i<chars.length;++i){
            char old = chars[i];
       
        for(char ch = 'a';ch<='z';++ch){
            if(old!=ch){
                chars[i] = ch;
                neighbors.add(new String(chars));
            }
        }
        chars[i] =old;
        }
        return neighbors;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值