【经典LeetCode算法题目专栏分类】【第4期】BFS广度优先算法:单词接龙、最小基因变化、二进制矩阵中的最短路径

《博主简介》

小伙伴们好,我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。
更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~
👍感谢小伙伴
们点赞、关注!

一般涉及到最小层数问题,要想到BFS。只要找到第一个符合条件的就是最小层数。

单词接龙

# 单向BFS

class Solution:

    def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:

        queue = [(beginWord, 1)]

        word_list = [ chr(ord('a') + i) for i in range(27)]

        wordList = set(wordList)

        n = len(beginWord)

        while queue:

            word, step = queue.pop(0)

            if word == endWord:

                return step

            for i in range(n):

                for c in word_list:

                    tmp = word[:i] + c + word[i+1:]

                    if tmp in wordList:

                        wordList.remove(tmp)

                        queue.append((tmp, step + 1))

        return 0

# 双向BFS

class Solution:

    def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:

        # 双向BFS

        word_set = set(wordList)

        if len(word_set) == 0 or endWord not in word_set:

            return 0

        if beginWord in word_set:

            word_set.remove(beginWord)

        visited = set()

        visited.add(beginWord)

        visited.add(endWord)

        begin_visited = set()

        begin_visited.add(beginWord)

        end_visited = set()

        end_visited.add(endWord)

        word_len = len(beginWord)

        step = 1

        # 简化成 while begin_visited 亦可

        while begin_visited and end_visited:

            if len(begin_visited) > len(end_visited):

                begin_visited, end_visited = end_visited, begin_visited

            next_level_visited = set()

            for word in begin_visited:

                word_list = list(word)

                for j in range(word_len):

                    origin_char = word_list[j]

                    for k in range(26):

                        word_list[j] = chr(ord('a') + k)

                        next_word = ''.join(word_list)

                        if next_word in word_set:

                            if next_word in end_visited:

                                return step + 1

                            if next_word not in visited:

                                next_level_visited.add(next_word)

                                visited.add(next_word)

                    word_list[j] = origin_char

            begin_visited = next_level_visited

            step += 1

        return 0

单词接龙2

单向遍历

class Solution:

    def findLadders(self, beginWord: str, endWord: str, wordList: List[str]) -> List[List[str]]:

        tree, words, n = collections.defaultdict(set), set(wordList), len(beginWord) 

        if endWord not in wordList: return []

        # found为是否找到最短路径的标识默认False

        # q存储当前层的单词, nq存储下一层的单词

        # tree[x]会记录单词x所有相邻节点的单词,即可能到达最终结果的路径

        found, q, nq = False, {beginWord}, set()

        while q and not found: # 当找到路径或者队列中没有元素时结束

            words -= set(q) # 从words列表中去除当前层的单词,避免重复使用

            for x in q: # 遍历当前层的所有单词

                for y in [x[:i]+c+x[i+1:] for i in range(n) for c in 'qwertyuiopasdfghjklzxcvbnm']: # 改变当前单词的每一个字符

                    if y in words: # 只关心在words集合中的单词

                        if y == endWord: # 如果找到了,将found置为True,不会再继续寻找下一层.

                            found = True

                        else: 

                            nq.add(y) # 准备下一层的单词集合

                        tree[x].add(y) # 记录x单词满足条件的下一个路径

            q, nq = nq, set() # 重新复制q与nq, q为下一次循环需遍历的单词集合,nq置为空

        def bt(x): 

            # 递归,在tree中寻找满足条件的路径

            # for y in tree[x] 遍历当前单词的相邻节点

            return [[x]] if x == endWord else [[x] + rest for y in tree[x] for rest in bt(y)]

        if found == False:

            return []

        return bt(beginWord)

# 双向遍历

class Solution:

    def findLadders(self, beginWord: str, endWord: str, wordList: List[str]) -> List[List[str]]:

        # 双向BFS

        tree, words, n = collections.defaultdict(set), set(wordList), len(beginWord)

        if endWord not in wordList: return []

        found, bq, eq, nq, rev = False, {beginWord}, {endWord}, set(), False

        while bq and not found:

            words -= set(bq)

            for x in bq:

                for y in [x[:i]+c+x[i+1:] for i in range(n) for c in 'qwertyuiopasdfghjklzxcvbnm']:

                    if y in words:

                        if y in eq: 

                            found = True

                        else: 

                            nq.add(y)

                        tree[y].add(x) if rev else tree[x].add(y)

            bq, nq = nq, set()

            if len(bq) > len(eq): 

                bq, eq, rev = eq, bq, not rev

        def bt(x): 

            return [[x]] if x == endWord else [[x] + rest for y in tree[x] for rest in bt(y)]

        return bt(beginWord)

最小基因变化

class Solution:

    def minMutation(self, start: str, end: str, bank: List[str]) -> int:

        #BFS

        possible_dict = {

                        "A": "CGT",

                        "C": "AGT",

                        "G": "ACT",

                        "T": "ACG"

                    }

        queue=[(start,0)]

        while queue:

            # 广度优先遍历模板

            (word, step)=queue.pop(0)

            if word ==end:

                return step

            

            for i, c  in enumerate(word):

                for p in possible_dict[c]:

                    # 从第0个位置开始匹配新的字符串

                    temp=word[:i]+p+word[i+1:]

                    # 在bank里面就处理(set中in操作复杂度是0(1))

                    if temp in bank: 

                        # 从bank里移除,避免重复计数

                        bank.remove(temp)  

                        # 加入队列,步数加1

                        queue.append((temp,step+1)) 

        return -1

二进制矩阵中的最短路径

class Solution:

    def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int:

        # BFS

        n = len(grid)

        if grid[n-1][n-1] == 1 or grid[0][0] == 1:

            return -1

        queue = [(0,0)]

        length = 1

        visited = set()

        visited.add((0,0))

        while queue:

            cur_nums = len(queue)

            for i in range(cur_nums):

                i,j = queue.pop(0)

                if i == n-1 and j == n-1:

                    return length

                for ni,nj in [(i-1,j-1),(i-1,j),(i-1,j+1),(i,j-1),(i,j+1),(i+1,j-1),(i+1,j),(i+1,j+1)]:

                    if 0<= ni < n and 0<= nj < n and (ni,nj) not in visited and grid[ni][nj] == 0:

                        visited.add((ni,nj))

                        queue.append((ni,nj))

            length += 1

        return -1

关于本篇文章大家有任何建议或意见,欢迎在评论区留言交流!

觉得不错的小伙伴,感谢点赞、关注加收藏哦!

欢迎关注下方GZH:阿旭算法与机器学习,共同学习交流~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/283278.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

7.实现任务的rebalance

1.设计 1.1 背景 系统启动后&#xff0c;所有任务都在被执行&#xff0c;如果这时某个节点宕机&#xff0c;那它负责的任务就不能执行了&#xff0c;这对有稳定性要求的任务是不能接受的&#xff0c;所以系统要实现rebalance的功能。 1.2 设计 下面是Job分配与执行的业务点…

高通平台开发系列讲解(AI篇)如何让MTCNN运行在SNPE

文章目录 一、使用到的工具1.1、SNPE特点1.2、SNPE特点二、环境配置2.1、Snpe的环境配置2.2、opencv的环境配置2.3、caffe的环境配置三、MTCNN网络组成四、基于SNPE运行MTCNN沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇章主要介绍如何使用高通平台SNPE运行MTCN…

GZ015 机器人系统集成应用技术样题5-学生赛

2023年全国职业院校技能大赛 高职组“机器人系统集成应用技术”赛项 竞赛任务书&#xff08;学生赛&#xff09; 样题5 选手须知&#xff1a; 本任务书共 24页&#xff0c;如出现任务书缺页、字迹不清等问题&#xff0c;请及时向裁判示意&#xff0c;并进行任务书的更换。参赛队…

【JVM从入门到实战】(八)垃圾回收(1)

内存泄漏&#xff1a;指的是不再使用的对象在系统中未被回收&#xff0c;内存泄漏的积累可能会导致内存溢出 什么是垃圾回收 Java中为了简化对象的释放&#xff0c;引入了自动的垃圾回收&#xff08;Garbage Collection简称GC&#xff09;机制。通过垃 圾回收器来对不再使用的…

什么是缓存击穿、缓存穿透、缓存雪崩?

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

6.鸿蒙app_hap_DevEco如何真机调试模式_app安装在手机中

真机调试 手机》设置》关于手机》HarmonyOS版本》软件版本&#xff0c;连续单击10次启动开发者模式 然后&#xff1a;设置》系统和更新》开发人员选项》打开USB调试功能。 电脑USB连接手机&#xff0c;手机USB连接类型&#xff0c;传文件&#xff08;不要选择仅充电&#xf…

gitlab ci pages

参考文章 gitlab pages是什么 一个可以利用gitlab的域名和项目部署自己静态网站的机制 开启 到gitlab的如下页面 通过gitlab.ci部署项目的静态网站 # build ruby 1/3: # stage: build # script: # - echo "ruby1"# build ruby 2/3: # stage: build …

Unity中URP下的菲涅尔效果实现(URP下的法线和视线向量怎么获取)

文章目录 前言一、实现思路二、实现原理我们可以由下图直观的感受到 N 与 L夹角越小&#xff0c;点积越接近&#xff08;白色&#xff09;1。越趋近90&#xff0c;点积越接近0&#xff08;黑色&#xff09; 三、实现URP下的菲涅尔效果1、我们新建一个Shader&#xff0c;修改为最…

gitlab 通过svn hook 触发

jenkins 起一个item 配置&#xff1a; 我选的自由风格的 源码管理配置 先选subversion 就是svn类型 url 设置project 的路径&#xff0c; 注意是工程&#xff0c;不是svn 顶层 添加一个账户来进行pull 等操作 选择添加的账号 构建触发器&#xff1a; &#xff0c;重要的是要自…

游戏运行中突然掉线是什么原因导致的

游戏平稳运行的原因只有一个&#xff0c;掉线的原因各有个的不同。这些不同的原因有常见&#xff0c;也有不常见的。但不管出于什么原因的掉线&#xff0c;带来的损失又是相同的。 首先最常见的原因就是攻击造成的 像CC&#xff0c;DDOS。CC会造成服务器资源的浪费&…

【PHP入门】1.1-PHP初步语法

-PHP语法初步- PHP是一种运行在服务器端的脚本语言&#xff0c;可以嵌入到HTML中。 1.1.1PHP代码标记 在PHP历史发展中&#xff0c;可以使用多种标记来区分PHP脚本 ASP标记&#xff1a; <% php代码 %>短标记&#xff1a; <? Php代码 ?>&#xff0c;以上两种…

ASP.NET MVC实战之权限拦截Authorize使用

1&#xff0c;具体的实现方法代码如下 public class CustomAuthorizeAttribute : FilterAttribute, IAuthorizationFilter{/// <summary>/// 如果需要验证权限的时候&#xff0c;就执行进来/// </summary>/// <param name"filterContext"></par…