当前位置: 首页 > 后端技术 > Python

BFS算法示例-解锁组合锁的最小数量

时间:2023-03-25 22:07:37 Python

BFS(广度优先搜索)的概念是最简单的图搜索算法之一,该算法也是许多重要图算法的原型。BFS算法的核心思想是将一些问题抽象成一个图。BFS和DFS的主要区别是:BFS找到的路径一定是最短的,但是代价是空间复杂度比DFS大很多。BFS经常出现的场景:问题本质是让你找到一张图片中起点到终点目标的最短距离。BFS算法其实就是这样做的。一般来说,寻找最短路径的时候会用到BFS,其他时候用的比较多的是DFS。传统的BFS框架从起点向四周传播,遇到终点就停止;而双向BFS同时从起点和终点开始扩散,当两侧有交集时停止。使用双向BFS的前提是必须提前知道终点。在哪里。不管传统BFS还是双向BFS,无论优化与否,从大O的角度来看,空间复杂度都是一样的。例子:有一个转盘锁,用四个圆形转盘打开密码锁。每个转盘共有0到9的10个数字,每个转盘可以上下旋转:比如把9转0,0转9,每次转只能转一个转盘代码(python)importcopyfromrich.consoleimportConsolefromrichimportprintconsole=Console()res=[]#~密码锁最少解锁次数#密码向上切换一次defplusOne(s,j):ch=[]foriins:ch.append(i)如果ch[j]=='9':ch[j]=str(0)else:ch[j]=str(int(ch[j])+1)#print(ch)res=''foriinch:res+=ireturnres#拨下一次密码defminusOne(s,j):ch=[]foriins:ch.append(i)ifch[j]=='0':ch[j]=str(9)否则:ch[j]=str(int(ch[j])-1)res=''foriinch:res+=ireturnres#传统BFS,从起点开始扩散defopenLock(deadends,target):#记录需要跳过的密码deads=[]foriindeadends:deads.append(i)#记录已经用完的密码,防止回滚。visited=[]q=[]#从起点开始广度优先搜索step=0q.append("0000")visited.append("0000")while(q!=None):sz=len(q)#将当前队列中的所有节点向周围展开foriinrange(sz):cur=q.pop(0)print(cur)#判断密码是否合法,是否到达末尾ifcurindeads:continueifcur==target:returnstep#将一个节点的未遍历相邻节点添加到队列中forjinrange(4):up=plusOne(cur,j)ifupnotinvisited:q.append(up)visited.append(up)down=minusOne(cur,j)ifdownnotinvisited:q.append(down)visited.append(down)step+=1return-1#BidirectionalBFSdefboth_openLock(deadends,target):#记录需要跳过的密码deads=[]foriindeadends:deads.append(i)#记录已经用完的密码,防止回滚。visited=[]q1=[]q2=[]#初始化起点和终点q1.append("0000")q2.append(target)step=0while(q1!=Noneandq2!=None):print('q1is'+str(q1))print('q2is'+str(q2))temp=[]forcurinq1:ifcurindeads:continueifcurinq2:returnstepvisited.append(cur)forjinrange(4):up=plusOne(cur,j)如果up不在访问范围内:temp.append(up)down=minusOne(cur,j)如果down未访问:temp.append(down)step+=1print('tempis'+str(temp))q1=q2q2=tempreturn-1deadends=["0007","5678"]target="2222"res=both_openLock(deadends,target)print(res)Flutter写的一个app,需要源码的可以私信~~火星简繁字体转换哄女朋友神器号测好和糟糕的电视节目直播表最好的笔记软件