【算法模板】BFS秒杀模板—附练习题(开启大海贼时代)(1)

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Python全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img



既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Python知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024c (备注Python)
img

正文

1、首先需要设置上下左右四个方向,且获取矩阵的长和宽。

2、写一个判断坐标是否越界的函数。

3、写核心模块bfs,首先需要有一个队列负责放入符合条件的坐标并对出队的坐标判断上下左右的坐标是否符合条件,如果符合条件则把岛屿沉入海底(变为0)。这样就能把一个岛屿全部沉入海底,并不会影响其他岛屿。

4、最后循环表格进行判断是否为陆地,在进行统计。

熊猫贱贱表情包

多源BFS:

在上述我们讲的是单源的BFS,而现在我们又来拓展一下多源的BFS

单源多源有什么区别呢?

下面是通过我的理解来给大家解释一下。

| 单源 | 多源 |

| :-: | :-: |

| 我们现在应该都是直到并发这个概念吧,而单源则就代表这个程序是不支持并发,每次就只能运行一个线程。 | 多源则可以形象的解释为可以并发,是多源BFS是可以同时进行搜索。 |

大概就是我们只要先把所有的陆地都入队,然后从各个陆地同时开始一层一层的向海洋扩散。

查看源图像


例题:地图分析

你现在手里有一份大小为 n x n 的 网格 grid,上面的每个 单元格 都用01标记好了。其中0代表海洋,1代表陆地。

请你找出一个海洋单元格,这个海洋单元格到离它最近的陆地单元格的距离是最大的,并返回该距离。如果网格上只有陆地或者海洋,请返回 -1

我们这里说的距离是「曼哈顿距离」( Manhattan Distance):(x0, y0) 和 (x1, y1)这两个单元格之间的距离是 |x0 - x1| + |y0 - y1|

示例一:

在这里插入图片描述

输入:grid = [[1,0,1],[0,0,0],[1,0,1]]

输出:2

解释:

海洋单元格 (1, 1) 和所有陆地单元格之间的距离都达到最大,最大距离为 2。

思路:本题就是一个多源的BFS扩散问题,按照上图我们可以让四个陆地都进行一个同时扩散,则需要几次同时扩撒本题的结果就是多少!

在这里插入图片描述

代码:

class Solution:

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

#检查边缘

def check(i,j,m,n):

if i >= 0 and j >= 0 and i < m and j < n:

return True

else:

return False

n = len(grid)

#上下四周的方向

d = [(1,0),(-1,0),(0,1),(0,-1)]

#用列表来当队列

queue = []

#减去自身的一次

step = -1

#先把所有岛屿都添加到队列中,准备多源BFS

for i in range(n):

for j in range(n):

if grid[i][j] == 1:

queue.append((i,j))

#判断如果测试例子中grid中都是1或者都是0,则返回-1,代表没有。

if len(queue) == 0 or len(queue) == n ** 2: return step

#使用队列对上下左右进行判断

while queue:

#这个for是一个多源BFS的一个关键点,表示同时扩散的重要地方!

for i in range(len(queue)):

x, y = queue.pop(0)#出队列

for k , l in d:

#判断周围的海

if check(x + k , y + l , n, n) and grid[x + k][y + l] == 0:

queue.append((x +k,y + l ))

grid[x + k ][ y + l ] = grid[x ][y ] + 1

step += 1#每循环一次就表示陆地对海洋的距离

return step#最后返回距离值

秒杀两题不够爽不要着急我专门为大家准备了更多的习题带给大家呢嘿嘿嘿嘿!!!!

| 题目 |

| :-- |

| 剑指 Offer II 105. 岛屿的最大面积 |

| 1254. 统计封闭岛屿的数目 |

| 1905. 统计子岛屿 |

| 994. 腐烂的橘子 |

| 太平洋大西洋水流问题 |

| 1091. 二进制矩阵中的最短路径 |

给我拿捏上面的习题!!!!

在这里插入图片描述



树类型模板

最常见的就是二叉树的层序遍历,我们能通过BFS算法模板直接套用进而秒杀。

例如:二叉树的层序遍历

题目:

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

示例一:

在这里插入图片描述

输入:root = [3,9,20,null,null,15,7]

输出:[[3],[9,20],[15,7]]

思路:

在本题中我们能把每层的节点都放在队列中,当访问每个节点的时候把节点的左右子树在添加到队列中(如果存在左右子树),同理还是访问子节点的子节点放到队列中,同时还需要输出每层的数据。

总所周知树也是图的一种,而我们一般使用多源BFS来访问数据。

代码模板:

Definition for a binary tree node.

class TreeNode:

def init(self, val=0, left=None, right=None):

self.val = val

self.left = left

self.right = right

class Solution:

def levelOrder(self, root: TreeNode) -> List[List[int]]:

#判断是否存在root

if not root :

return []

#用来统计输出的数据

res = []

#设置一个队列,并把头节点放入队列中

queue = [root]

#开始对每一层的节点进行访问

while queue:

#统计每一层节点的val值

temp = []

#获取每层的节点数

size = len(queue)

#进行一个多源的BFS

for _ in range(size):

#出队列

r = queue.pop(0)

#添加值

temp.append(r.val)

#判断左右子节点是否存在,如果存在则入队

if r.left:

queue.append(r.left)

if r.right:

queue.append(r.right)

#把每层的数据放入res中

res.append(temp)

return res

树的BFS习题已经给大家准备好了,给我直接秒杀他们!!!

| 题目 |

| — |

| 111. 二叉树的最小深度 |

| 剑指 Offer II 045. 二叉树最底层最左边的值 |

| #107 二叉树的层序遍历 II |

| #429 N 叉树的层序遍历 |

| #103 二叉树的锯齿形层序遍历 |

| |

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


图论类型模板

众所周知BFS其实就图的一种搜索方法,而在我们刷题的航向上经常遇见一些图的BFS搜索方法,所以今天就给大家带来图的BFS的秒杀解题模板。话不多说,直接上列题。

例题:310. 最小高度树

题目:

树是一个无向图,其中任何两个顶点只通过一条路径连接。 换句话说,一个任何没有简单环路的连通图都是一棵树。

给你一棵包含n个节点的树,标记为0n - 1。给定数字n和一个有n - 1条无向边的edges列表(每一个边都是一对标签),其中edges[i] = [ai, bi]表示树中节点aibi之间存在一条无向边。

可选择树中任何一个节点作为根。当选择节点x作为根节点时,设结果树的高度为h。在所有可能的树中,具有最小高度的树(即,min(h))被称为 最小高度树 。

请你找到所有的 最小高度树 并按 任意顺序 返回它们的根节点标签列表。

树的 高度 是指根节点和叶子节点之间最长向下路径上边的数量。

示例:

在这里插入图片描述

输入n = 4, edges = [[1,0],[1,2],[1,3]]

输出:[1]

解释:如图所示,当根是标签为 1 的节点时,树的高度是 1 ,这是唯一的最小高度树。

思路:

本题其实就是看谁的子节点多,就让谁来当作根节点。通过上图的示例我们也能看见1的根节点是比较多的一个节点,所以如果它作为根节点则就可以使树的长度达到最小。其实我们这个还能把这个树(或者图)看成是一个洋葱我们从外面一层层的拨开它的皮(节点(入度)为一的节点)。直到到最后一个能获取最后一个(或者多个节点)然后放到数组中并返回该数组中的所有节点。

我们可以通过下面画的一个简略图能大概的分析这个剥洋葱!(画的有点丑,大家别嫌弃嘿嘿嘿嘿)

在这里插入图片描述

通过上图能看到最中心的两个节点是最后一层拨开的节点,我们把它放在数组里面返回即可。

代码:

class Solution:

def findMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]:

#判断这个数是否小于两个节,小于就返回其有多少个就返回多少个。

if len(edges) < 2:

return [i for i in range(n)]

#统计1到n-1的每一个节点。

tree = [[] for i in range(n)]

#用for循环把每个相连的节点放入里面,构建出我们想要的图。

for i, j in edges:

tree[i].append(j)

tree[j].append(i)

#用一个数组对每个节点的入度进行统计

d = [len(i) for i in tree]

#先把入度为一的节点放入队列中,也就是上图中最外面的那些节点。

queue = [i for i in range(len(d)) if d[i] == 1]

res = None

#使用队列进行循环

while queue:

res = list()

#进行多源BFS

for j in range(len(queue)):

如果你也是看准了Python,想自学Python,在这里为大家准备了丰厚的免费学习大礼包,带大家一起学习,给大家剖析Python兼职、就业行情前景的这些事儿。

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、学习软件

工欲善其必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、全套PDF电子书

书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。

四、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

五、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

成为一个Python程序员专家或许需要花费数年时间,但是打下坚实的基础只要几周就可以,如果你按照我提供的学习路线以及资料有意识地去实践,你就有很大可能成功!
最后祝你好运!!!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注python)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
252731a671c1fb70aad5355a2c5eeff0.png)

五、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

成为一个Python程序员专家或许需要花费数年时间,但是打下坚实的基础只要几周就可以,如果你按照我提供的学习路线以及资料有意识地去实践,你就有很大可能成功!
最后祝你好运!!!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注python)
[外链图片转存中…(img-etKg48jO-1713219799999)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 16
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值