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

news2024/10/6 8:40:52

《博主简介》

小伙伴们好,我是阿旭。专注于人工智能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.coloradmin.cn/o/1321769.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用bash写脚本

本章主要介绍如何使用bash写脚本。 了解通配符 了解变量 了解返回值和数值运算 数值的对比 判断语句 循环语句 grep的用法是“grep 关键字 file”&#xff0c;意思是从file中过滤出含有关键字的行。 例如&#xff0c;grep root /var/log/messages&#xff0c;意思是从/var/log/…

家居家纺品牌网站建设的作用是什么

家居家纺企业往往规模很高&#xff0c;比如被褥、枕头床单等都是家家必备的&#xff0c;市场规模连年增长&#xff0c;但在实际经营中&#xff0c;随着互联网深入各个行业&#xff0c;传统企业线上化能力不足&#xff0c;也产生了许多痛点。 1、品牌传播难 家居家纺企业以批发…

PCL点云处理之点云置平(拟合平面绕中心旋转到绝对水平)(二百二十七)

PCL点云处理之点云置平(绕中心旋转到绝对水平)(二百二十七) 一、什么是点云置平二、算法流程三、算法实现一、什么是点云置平 有时候,我们处理的点云平面并非位于水平面,而是位于某个任一三维平面上,而大多数算法又只能在水平面处理,或者水平面的点云处理是相对更简单…

9.鸿蒙app用户界面的跳转abilityslice的跳转

9.用户界面的跳转abilityslice的跳转&#xff0c;值传递&#xff0c;数值累加 首页页面显示1&#xff0c;第2页显示2&#xff0c;再次点击返回首页3。。。 MainAbilitySlice.java 关键代码&#xff1a; 点击事件 text.setClickedListener(new Component.ClickedListener() …

[自动化运维工具]ansible简单介绍和常用模块

ansible 源操作主机功能 自动化运维&#xff08;playbook剧本yaml&#xff09; 是基于python开发的一个配置管理和应用部署工具&#xff0c;在自动化运维中&#xff0c;现在还是异军突起 ansible能批量配置&#xff0c;部署&#xff0c;管理上千台主机&#xff0c;类似于xshell…

安全生产隐患排查治理信息化系统软件

安全隐患排查系统实现对重大危险源企业、安全隐患信息的登记、整改、复查、分类和统计。系统涵盖了安全隐患排查整治工作的各项基本内容&#xff0c;实现以安全隐患排查整治业务流为主线&#xff0c;处理流程简洁清晰、快速灵活&#xff1b;以排查整治流程为干线&#xff0c;快…

5行Python实现验证码识别,太稳了

很久之前&#xff0c;分享过一次Python代码实现验证码识别的办法。 当时采用的是pillowpytesseract&#xff0c;优点是免费&#xff0c;较为易用。但其识别精度一般&#xff0c;若想要更高要求的验证码识别&#xff0c;初学者就只能去选择使用百度API接口了。 但其实百度API接…

Linux-----21、挂载

# 挂载命令 将硬件资源&#xff0c;或文件资源&#x1f4bf;&#xff0c;和&#x1f4c2;空目录&#x1f517;连接起来的过程 # mount linux 所有存储设备都必须挂载使用&#xff0c;包括硬盘 ​ 命令名称&#xff1a;mount ​ 命令所在路径&#xff1a;/bin/mount ​ 执行…

无懈可击的防泄密之旅:迅软DSE在民营银行的成功实践

客户简要介绍 某股份有限公司主体是中部地区的民营银行&#xff0c;由其母公司联合9家知名民营企业共同发起设立。正式开业于2016年&#xff0c;紧紧围绕目标产业生态圈和消费金融&#xff0c;着力打造产业银行、便捷银行、数字银行、财富管理银行为一体的BEST银行&#xff0c…

学习Java第74天,Ajax简介

什么是ajax AJAX Asynchronous JavaScript and XML&#xff08;异步的 JavaScript 和 XML&#xff09;。 AJAX 不是新的编程语言&#xff0c;而是一种使用现有标准的新方法。 AJAX 最大的优点是在不重新加载整个页面的情况下&#xff0c;可以与服务器交换数据并更新部分网页…

基于Java SSM框架实现二手车交易网站系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现二手车交易网站系统演示 摘要 二手车交易网站采用B/S模式&#xff0c;促进了二手车交易网站的安全、质量、快捷的发展。传统的管理模式还处于手工处理阶段&#xff0c;管理效率极低&#xff0c;随着用户的不断增多&#xff0c;传统基于手工管理模式已经无…

Redis7--基础篇9(SpringBoot集成Redis)

1. jedis、lettuce、Redistemplate的关系 第一代为jedis&#xff0c;之后推出了lettuce&#xff0c;然后springboot继承了Redistemplate&#xff0c;现推荐使用Redistemplate。 总的来说&#xff0c;jedis、lettuce、Redistemplate都是java操作Redis数据库的驱动。 2. 本地Ja…

MapReduce和Yarn部署+入门

看的黑马视频记的笔记 目录 1.入门知识点 分布式计算&#xff1a; 概念&#xff1a; 两种模式&#xff1a; MapReduce&#xff08;分布式计算&#xff0c;分散汇总模式&#xff09; 概念 执行原理 注&#xff1a; Yarn&#xff08;分布式资源调度&#xff09; 概述 Y…

探讨小鹏汽车CAN通讯协议分析破解过程数据研究技术应用

当前新能源电动汽车设计日益复杂&#xff0c;为提高舒适性、功能性、提升性能和确保更高的安全性&#xff0c;很多汽车的设计中融入了更复杂的功能。包括了雷达、激光雷达、自适应巡航、L2以上自动驾驶系统&#xff0c;高级驾驶辅助系统、盲区监测等等。安装在汽车上的传感器和…

代码魔法:递归嵌套的《迷宫之旅》算法解析

前言 在代码的舞台上&#xff0c;递归算法的奇迹就如同魔法一般令人叹为观止。本文以经典的迷宫问题为基础&#xff0c;通过递归嵌套的方式&#xff0c;带你踏上一场神奇的迷宫之旅。 迷宫规则 迷宫由一个二维数组表示&#xff0c;其中0表示可通行的路径&#xff0c;1表示墙…

泛型(泛型类、接口及方法)——学习推荐版,通俗易懂讲解

泛型定义及分类 1.泛型类 类型变量其实就是一个标识符&#xff0c;一般用大写字母表示&#xff0c;如K&#xff0c;T&#xff0c;E&#xff0c;V&#xff0c;当然也可以多个字母或数字的组合&#xff0c;只要满足标识符的定义规则就都可以。 形式1 若写成MyArrayList<> …

UE5 C++(六)— 枚举UENUM、结构体USTRUCT和补充属性说明符

文章目录 枚举&#xff08;ENUM&#xff09;第一种方式第二种方式 结构体&#xff08;USTRUCT&#xff09;补充属性说明符&#xff08;ExposeOnSoawn&#xff09;结构体创建数据表格 枚举&#xff08;ENUM&#xff09; 第一种方式 定义枚举 UENUM(BlueprintType) namespace …

Vue中英文翻译小结

背景&#xff1a;时局艰难&#xff0c;后端开发被强制写了vue&#xff0c;这不有个需求是中英文翻译&#xff0c;特此记录下&#xff0c;该怎么个翻译法子。 先引入全局的路由国际化文件&#xff0c;zh.js 和 en.js 1.关于插值表达Button里面 {{ $t(reinsop.common.back) }} …

制造业CRM选型注意事项:有这些功能的系统更好用

当前&#xff0c;推动制造业数字化转型已成时代发展趋势。为了适应这一趋势&#xff0c;制造业使用CRM管理系统是非常重要的。那么&#xff0c;制造业CRM应该怎么选&#xff1f; 1、全方位客户管理 订单价值大&#xff0c;交货周期长&#xff0c;客户开发难。。。这一直是制造…

MySQL job 定时任务

目录 介绍 优点&#xff1a; 缺点&#xff1a; 使用场景&#xff1a; 案例 创建表 -- 创建定时任务 每一分钟插入一条数据 执行结果 -- 查询定时任务 ENABLED--启用 DISABLED--禁用 -- 查询定时任务 -- 启用定时任务 ​-- 禁用定时任务 ​-- 删除定时任务 …