广度优先搜索算法编程题代表——单词接龙

本文介绍了如何使用广度优先搜索算法解决单词接龙问题,给出了从单词'beginWord'到'endWord'的最短转换序列。讨论了初始的未优化解决方案可能导致的时间复杂度问题,并提出了通过HashSet优化查询效率的方法来提高性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

广度优先搜索算法编程题代表——单词接龙

题目描述:
字典 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。

二话不说,先看题,在题中我们不难发现这种字眼——”最短“,我们知道作为广度优先搜索算法,其最大的功能就是找最短路径,为什么?因为它是优先走离它最近的,一但满足条件,立刻停止搜索,这也就是为什么广度优先搜索为什么适合找最短路径问题了。
首先,由于一次只能变一个字母,并且转换过程中的中间单词必须是字典 wordList 中的单词,所以每次变一个字母都要和字典中的单词进行比对,这样导致了大量反复的比较,这样时间复杂度就成为了:
O(N*单词长度)
由于测试用例可能数据量相当庞大,所以极有可能超时,此时先上一个没有优化的代码:

class Solution {
    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        Queue<String>queue=new LinkedList<>();
        HashSet<String>set=new HashSet<>();//防止重复遍历一个单词
        boolean flag=false;
        for(String x:wordList){
            if(x.equals(endWord)){//有结果单词
                flag=true;
            }
            int count=0;
            for(int i=0;i<beginWord.length();++i){
                if(beginWord.charAt(i)!=x.charAt(i)){
                    count++;
                }
            }
            if(count==1){//存在改变一个字母的结果单词
                queue.offer(x);
                set.add(x);
            }
        }
        if(!flag){//没有结果单词
            return 0;
        }
        int end=1;
        while(!queue.isEmpty()){
            int len=queue.size();
            while(len>0){
                String y=queue.poll();
                if(y.equals(endWord)){
                    return end+1;
                }
               for(String x:wordList){
                 int count=0;
                  for(int i=0;i<beginWord.length();++i){
                    if(y.charAt(i)!=x.charAt(i)){
                    count++;
                    }
                }
            if(count==1&&!set.contains(x)){
                queue.offer(x);
            }
               }
               len--;
            }
            end++;
        }
        return 0;
    }
}

测试用例:
“cet” “ism” [“kid”,“tag”,“pup”,“ail”,“tun”,“woo”,“erg”,“luz”,“brr”,“gay”,“sip”,“kay”,“per”,“val”,“mes”,“ohs”,“now”,“boa”,“cet”,“pal”,“bar”,“die”,“war”,“hay”,“eco”,“pub”,“lob”,“rue”,“fry”,“lit”,“rex”,“jan”,“cot”,“bid”,“ali”,“pay”,“col”,“gum”,“ger”,“row”,“won”,“dan”,“rum”,“fad”,“tut”,“sag”,“yip”,“sui”,“ark”,“has”,“zip”,“fez”,“own”,“ump”,“dis”,“ads”,“max”,“jaw”,“out”,“btu”,“ana”,“gap”,“cry”,“led”,“abe”,“box”,“ore”,“pig”,“fie”,“toy”,“fat”,“cal”,“lie”,“noh”,“sew”,“ono”,“tam”,“flu”,“mgm”,“ply”,“awe”,“pry”,“tit”,“tie”,“yet”,“too”,“tax”,“jim”,“san”,“pan”,“map”,“ski”,“ova”,“wed”,“non”,“wac”,“nut”,“why”,“bye”,“lye”,“oct”,“old”,“fin”,“feb”,“chi”,“sap”,“owl”,“log”,“tod”,“dot”,“bow”,“fob”,“for”,“joe”,“ivy”,“fan”,“age”,“fax”,“hip”,“jib”,“mel”,“hus”,“sob”,“ifs”,“tab”,“ara”,“dab”,“jag”,“jar”,“arm”,“lot”,“tom”,“sax”,“tex”,“yum”,“pei”,“wen”,“wry”,“ire”,“irk”,“far”,“mew”,“wit”,“doe”,“gas”,“rte”,“ian”,“pot”,“ask”,“wag”,“hag”,“amy”,“nag”,“ron”,“soy”,“gin”,“don”,“tug”,“fay”,“vic”,“boo”,“nam”,“ave”,“buy”,“sop”,“but”,“orb”,“fen”,“paw”,“his”,“sub”,“bob”,“yea”,“oft”,“inn”,“rod”,“yam”,“pew”,“web”,“hod”,“hun”,“gyp”,“wei”,“wis”,“rob”,“gad”,“pie”,“mon”,“dog”,“bib”,“rub”,“ere”,“dig”,“era”,“cat”,“fox”,“bee”,“mod”,“day”,“apr”,“vie”,“nev”,“jam”,“pam”,“new”,“aye”,“ani”,“and”,“ibm”,“yap”,“can”,“pyx”,“tar”,“kin”,“fog”,“hum”,“pip”,“cup”,“dye”,“lyx”,“jog”,“nun”,“par”,“wan”,“fey”,“bus”,“oak”,“bad”,“ats”,“set”,“qom”,“vat”,“eat”,“pus”,“rev”,“axe”,“ion”,“six”,“ila”,“lao”,“mom”,“mas”,“pro”,“few”,“opt”,“poe”,“art”,“ash”,“oar”,“cap”,“lop”,“may”,“shy”,“rid”,“bat”,“sum”,“rim”,“fee”,“bmw”,“sky”,“maj”,“hue”,“thy”,“ava”,“rap”,“den”,“fla”,“auk”,“cox”,“ibo”,“hey”,“saw”,“vim”,“sec”,“ltd”,“you”,“its”,“tat”,“dew”,“eva”,“tog”,“ram”,“let”,“see”,“zit”,“maw”,“nix”,“ate”,“gig”,“rep”,“owe”,“ind”,“hog”,“eve”,“sam”,“zoo”,“any”,“dow”,“cod”,“bed”,“vet”,“ham”,“sis”,“hex”,“via”,“fir”,“nod”,“mao”,“aug”,“mum”,“hoe”,“bah”,“hal”,“keg”,“hew”,“zed”,“tow”,“gog”,“ass”,“dem”,“who”,“bet”,“gos”,“son”,“ear”,“spy”,“kit”,“boy”,“due”,“sen”,“oaf”,“mix”,“hep”,“fur”,“ada”,“bin”,“nil”,“mia”,“ewe”,“hit”,“fix”,“sad”,“rib”,“eye”,“hop”,“haw”,“wax”,“mid”,“tad”,“ken”,“wad”,“rye”,“pap”,“bog”,“gut”,“ito”,“woe”,“our”,“ado”,“sin”,“mad”,“ray”,“hon”,“roy”,“dip”,“hen”,“iva”,“lug”,“asp”,“hui”,“yak”,“bay”,“poi”,“yep”,“bun”,“try”,“lad”,“elm”,“nat”,“wyo”,“gym”,“dug”,“toe”,“dee”,“wig”,“sly”,“rip”,“geo”,“cog”,“pas”,“zen”,“odd”,“nan”,“lay”,“pod”,“fit”,“hem”,“joy”,“bum”,“rio”,“yon”,“dec”,“leg”,“put”,“sue”,“dim”,“pet”,“yaw”,“nub”,“bit”,“bur”,“sid”,“sun”,“oil”,“red”,“doc”,“moe”,“caw”,“eel”,“dix”,“cub”,“end”,“gem”,“off”,“yew”,“hug”,“pop”,“tub”,“sgt”,“lid”,“pun”,“ton”,“sol”,“din”,“yup”,“jab”,“pea”,“bug”,“gag”,“mil”,“jig”,“hub”,“low”,“did”,“tin”,“get”,“gte”,“sox”,“lei”,“mig”,“fig”,“lon”,“use”,“ban”,“flo”,“nov”,“jut”,“bag”,“mir”,“sty”,“lap”,“two”,“ins”,“con”,“ant”,“net”,“tux”,“ode”,“stu”,“mug”,“cad”,“nap”,“gun”,“fop”,“tot”,“sow”,“sal”,“sic”,“ted”,“wot”,“del”,“imp”,“cob”,“way”,“ann”,“tan”,“mci”,“job”,“wet”,“ism”,“err”,“him”,“all”,“pad”,“hah”,“hie”,“aim”,“ike”,“jed”,“ego”,“mac”,“baa”,“min”,“com”,“ill”,“was”,“cab”,“ago”,“ina”,“big”,“ilk”,“gal”,“tap”,“duh”,“ola”,“ran”,“lab”,“top”,“gob”,“hot”,“ora”,“tia”,“kip”,“han”,“met”,“hut”,“she”,“sac”,“fed”,“goo”,“tee”,“ell”,“not”,“act”,“gil”,“rut”,“ala”,“ape”,“rig”,“cid”,“god”,“duo”,“lin”,“aid”,“gel”,“awl”,“lag”,“elf”,“liz”,“ref”,“aha”,“fib”,“oho”,“tho”,“her”,“nor”,“ace”,“adz”,“fun”,“ned”,“coo”,“win”,“tao”,“coy”,“van”,“man”,“pit”,“guy”,“foe”,“hid”,“mai”,“sup”,“jay”,“hob”,“mow”,“jot”,“are”,“pol”,“arc”,“lax”,“aft”,“alb”,“len”,“air”,“pug”,“pox”,“vow”,“got”,“meg”,“zoe”,“amp”,“ale”,“bud”,“gee”,“pin”,“dun”,“pat”,“ten”,“mob”]
眼睛疼不疼!!!!!!
所以我又进行了优化:
1.不再采用顺序表查询当前单词是否在字典中,而替换成了HashSet,因为HashSet的查询时间复杂度是O(1);
2.不在每次在字典中查找当前单词变一个字母是否在字典中是否存在,因为时间复杂度在那摆着呢,所以,直接枚举改变一个字母所产生的所有结果,再联合HashSet的快速查询,可以有意想不到的效果;
下面放代码:

class Solution {
    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        Queue<String>queue=new LinkedList<>();
        HashSet<String>set=new HashSet<>(wordList);//单词表
        HashSet<String>visited=new HashSet<>();//防止重复查询一个单词
        visited.add(beginWord);
        queue.offer(beginWord);
        int end=1;
        while(!queue.isEmpty()){
            int size=queue.size();
            while(size>0){
                String next=queue.poll();
               char[]x=next.toCharArray();
               for(int i=0;i<x.length;++i){
                   char xx=x[i];
                   for(char c='a';c<='z';++c){
                       if(c!=xx){
                           x[i]=c;
                           String newWord=new String(x);
                           if(set.contains(newWord)){
                               if(newWord.equals(endWord)){
                                   return end+1;
                               }
                               if(!visited.contains(newWord)){
                                   visited.add(newWord);
                                   queue.offer(newWord);
                               }
                           }
                       }
                   }
                   x[i]=xx;
               }
               size--;
            }
            end++;
        }
        return 0;
    }
}

运行结果:
在这里插入图片描述
写的不好的地方还请担待,一起努力,不妨关注,点赞一波吧。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值