关于图论中的层序遍历bfs

最近刷了一些图论层序遍历的题目,想做一个小小总结。

一般图论貌似都可以使用dfs或者bfs来做,我现在在专攻bfs这个模块。

一共刷了四道题:迷宫最近出口、最短的桥、最小基因变化、跳跃游戏

我认为前两题可以算是一个类型的题目,是根据当前位置四周(上下左右)的情况判断是否可以走、或者是否是岛屿来处理

迷宫入口最近出口的话,需要定义dx=[1,0,-1,0] dy=[0,1,0,-1]来提供一个单位矢量,我理解的思路是定义一个queue(用来存放要去的地方和走的路程)(like:queue=deque([(entrance[0],entrance[1],0)]))然后每走过一个地方都要把原来的地方定义为墙或者“-1”这样子防止再走回去。

然后路程就可以写为如下内容。

while queue:
    x,y,num=queue.popleft()
    for index in range(4):
        nx=x+dx[index]
        ny=y+dy[index]
        if 0<=nx<m and 0<=ny<n and maze[nx][ny]=='.':
            if nx==0 or nx==m-1 or ny==0 or ny==n-1:
                return num
            queue.append((nx,ny,num+1))
            maze[nx][ny]='+'
return -1

首先把queue队列里面的前置内容提取出来,然后对其四周进行遍历,首先进行一个大的条件筛选(很重要!方便后续操作)把在矩阵范围内且路径为路的条件下处理,先定义一个if,在这个if下面再判断一下节点是否到达边界(到了就直接return),如果没到边界的话就把节点加入queue并且把节点设置为已到访。

最短的桥需要注意一个问题就是,题目说的岛屿只有两个,所以一触碰到岛屿就可以进行四周轮询。

这个题目的思路是两层for循环,第二层for循环处理具体岛屿节点,只要触碰到了岛屿就append进入island,然后在接下来去进行一个while True:循环(在和上述触碰于同一个for循环里面),while True:有一个条件是必须碰到另一个island才停下来,如果没碰到的话就把海洋(0)也添加进queue中(这个queue是while循环独有的,queue都是存放需要遍历的节点)然后step+=1

最小基因变化这道题主要是看对字符串的处理,拼接字符串的方法最建议使用切片(like:q=u[:i]+v+u[i+1:])

B=['A','C','G','T']
bank_set=set(bank)
queue=deque([start])
if start in bank_set:
    bank_set.remove(start)
res=0
while queue:
    for _ in range(len(queue)):
        x=queue.popleft()
        for index in range(len(x)):
            for i in B:
                nx=x[:index]+i+x[index+1:]
                if nx==end:
                    return res
                if nx in bank_set:
                    queue.append(nx)
                    bank_set.remove(nx)
    res+=1
return False

最后一道题是跳跃游戏,我觉得跳跃游戏还是比较好整的,但是当时没想出来

跳跃游戏是这样的,给一个arr=[4,2,3,0,3,1,2],start=5 然后问每一次能跳到i+arr[i] i-arr[i]两个index,问能不能跳到0那里?

used=set()
while queue:
    for _ in range(len(queue)):
        i=queue.popleft()
            for index in [i-arr[i],i+arr[i]]:
                if 0<=index<n and index not in used:
                    if arr[index]==0:
                        return True
                    used.add(index)
                    queue.append(index)
return False

像这种最开始要for _ in range(len(queue)):的是可以保证把queue里面的内容先清一清,加上不会碍事(可以看到queue.popleft()就直接加上for这个语句?我瞎想的,后面再验证)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值