zoukankan      html  css  js  c++  java
  • LeetCode 11.05每日一题 127. 单词接龙【中等】

    单词接龙 

    题目:

    给定两个单词(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" 不在字典中,所以无法进行转换。
    
    

    如果不了解bfs,本题相当难度的,搜索最短路径,需要用到广度优先遍历的思想,bfs和dfs的理解可以参考

    思路:

    从起点词出发,每次变动一个字母,经过 n 次变换,变成终点词,希望 n 尽量小。
    找出邻接关系,比如hit它变一个字母会变成_it、h_t、hi_形式的单词。
    然后看这个新词是否存在于单词表,如果存在,就找到了一个下一层的转换词。
    同时,要避免重复访问,比如hit->hot->hit这样变回来,只会徒增转换的长度。
    因此,要将下一个转换词从单词表中删除(单词表的单词是唯一的)。

    /**
     * @param {string} beginWord
     * @param {string} endWord
     * @param {string[]} wordList
     * @return {number}
     */
    var ladderLength = function(beginWord, endWord, wordList) {
        var queue=[];
        var wordset=new Set(wordList);
        var s="abcdefghijklmnopqrstuvwxyz"
        queue.push([beginWord, 1]);
        while(queue.length){
            var [word,level]=queue.shift();
            if(word==endWord){
                return level;
            }
            for(var i=0;i<word.length;i++){
                for(var j=0;j<s.length;j++){
                    var temp=word.substring(0,i)+s[j]+word.substring(i+1);
                    if(wordset.has(temp)){
                        queue.push([temp, level+1]);
                        wordset.delete(temp);
                    }
                }
                
            }
        }
        return 0;
    
    };

     还有另外一个思路:不从单词表中去匹配,而是使用issimilar方法去比较两个单词是否差1。

    /**
     * @param {string} beginWord
     * @param {string} endWord
     * @param {string[]} wordList
     * @return {number}
     */
    var ladderLength = function(beginWord, endWord, wordList) {
        var queue=[];//维护一个队列
        queue.push([beginWord, 1]);
        var issimilar=function(f,s){//判断两数差一位
            var count=0;
            for(var i=0;i<f.length;i++){
                if(f[i]!=s[i]){
                    count++;
                    if(count>=2) return false; //加了判断,运行时间少了250ms
                }
            }
            return count==1;
        }
        while(queue.length){//BFS 广度优先搜索
            var [word,level]=queue.shift();
            if(word==endWord){//当出列的单词和终点词相同,说明遇到了终点词,返回它的 level。
                return level;
            }
            for(var i=0;i<wordList.length;i++){
                if(issimilar(word,wordList[i])){//判断两数是否差一
                    queue.push([wordList[i], level+1]);//将它入列,它的 level+1,并从单词表中删去这个词。
                    wordList.splice(i,1);  //相较于delete wordList[i] 运行时间少了200ms
                    i--;
                }
            }
        }
        return 0;//没有遇到终点词,没有路径通往终点,返回 0。
    };

     

    运行结果内存消耗大大减少,主要减少了wordset这块。耗时增加了,主要是比较差1的方法。

  • 相关阅读:
    Linux下PCI设备驱动程序开发 PCI驱动程序实现(三)
    一个动态内存管理模块的实现
    【Linux device driver】设备驱动程序概述(一)
    Linux PCI设备驱动程序开发 PCI 体系结构(一)
    [linux driver]用I/O命令访问PCI总线设备配置空间
    【Linux device driver】网络设备驱动程序(二)
    【Linux device driver】网络设备驱动注意的问题(三)
    C++中的引用、const引用和非const引用
    C++的数组和指针
    “指向const对象的指针” 和 “const指针”
  • 原文地址:https://www.cnblogs.com/liangtao999/p/13934803.html
Copyright © 2011-2022 走看看