当青训营遇上码上掘金之寻友之旅
本文是「青训营 X 码上掘金」主题创作活动参加作品。题目见juejin.cn/post/718775… 第4题
基本思路
本题我的想法是基本的BFS。题目给出了两种步进的方法:
- 向前或向后1步
- 从到()
当前进到某个节点时,下一个节点有三种选择:
因此可以将可能的路径模拟为一个以起点坐标为根的三叉树,从到通过该路径达到的步数为节点的层数。为达到路径耗时最短的效果,只需使用BFS层序遍历三叉树,当第一次遇到终点节点的坐标时就可以停止,此时的层数就是最短路径。
考虑剪枝。如果一个坐标已经访问过,则不应该被再次访问。因此出现这种情况时应该停止访问该节点下的节点。
三叉树的空间占用很大,考虑使用队列模拟层序遍历过程,以压缩空间占用。使用collections.orderdict类模拟三叉树的遍历过程,因为该类具有双端队列的特点,并且保存了字典项,方便用值进行查找。
代码如下:
'''
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K 0≤N , K≤100 000 并且小码在自己家原地不动等待小青。小青有两种交通方式可选 步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2xX (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
'''
import math
import collections
if __name__=="__main__":
n,k=input().split()
n,k=int(n),int(k)
que= collections.OrderedDict({n:0})
while que:
tmp=que.popitem(last=False)#FIFO
if tmp[0]==k:
print("Success ",tmp[1])
break
if tmp[0]-1>0 and tmp[0]-1 not in que:
que[tmp[0]-1]=tmp[1]+1
if tmp[0]+1>=100000 and tmp[0]+1 not in que:
que[tmp[0]+1]=tmp[1]+1
if tmp[0] * 2 <= 100000 and tmp[0]*2 not in que:
que[tmp[0]*2]=tmp[1]+1
BFS的时间空间复杂度应该都为。如果你有其他的思路或者更好的解法,亦或者你发现了文章出现了错误或有不足,欢迎在评论区和我交流。