寻友之旅BFS解法

144 阅读3分钟

当青训营遇上码上掘金

  • 主题 3:寻友之旅

    小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
    步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
    公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)

    请帮助小青通知小码,小青最快到达时间是多久?
    输入: 两个整数 N 和 K
    输出: 小青到小码家所需的最短时间(以分钟为单位)

本题是经典的BFS(广度优先搜索)题目,使用广度优先搜索可以找出最短路径。

借助队列和标志结点是否已访问的数组实现BFS。

标记某结点已访问,说明到达该结点的最短路径已找到,不必再更新其最短路径。

伪代码

先将N和当前位置分钟数min=0入队

第一次遍历,队头出队,判断当前位置是否和小码的相同,如果是则直接返回当前分钟数;反之判断该队头可能的下一步nextX(X-1、X+1、X * 2),是否已经访问过,如果没有访问过,并且下一步符合0<=nextX<=100000,如果是,则将当前位置的分钟数+1,入队

第二次遍历,队头出队,判断当前位置是否和小码的相同,如果是则直接返回当前分钟数;反之判断该队头可能的下一步nextX(X-1、X+1、X * 2),是否已经访问过,如果没有访问过,并且下一步符合0<=nextX<=100000,如果是,则入队,则将当前位置的分钟数+1,入队

......

第n次遍历,队头出队,判断当前位置是否和小码的相同,如果是则直接返回当前分钟数;反之判断该队头可能的下一步nextX(X-1、X+1、X * 2),是否已经访问过,如果没有访问过,并且下一步符合0<=nextX<=100000,如果是,则入队,则将当前位置的分钟数+1,入队

示例数据N=1,K=3

下图的最上方为队列内容,每个格子都是一次遍历入队的情况

蓝字为入队,绿字为出队,红字为不符合入队要求的可能下一步,黑色字体为当前入队结点的分钟数

最后画了一个树状图,方便理解。

  • 1入队
  • 1出队,检测1是否等于K,0、2入队
  • 0出队,检测0是否等于K,没有符合要求的下一步
  • 2出队,检测2是否等于K,3、4入队,1不符合要求
  • 3出队,此时检测到3==K,找到最短路径,分钟数为2

63e1e34851cdf742354e74af2c9510e.png

代码

定义一个结构体,里面包含当前位置和到达当前位置所消耗的分钟数(到达当前位置的最短路径),使用一个队列,队列存放前面定义的结构体,定义一个标记结点是否已经访问过的数组visit[MAXN+5],MAXN==100000

code.juejin.cn/pen/7198453…