寻友之旅 | 青训营 X 码上掘金

16 阅读2分钟

当青训营遇上码上掘金


题目

下面是主题3题目的描述:

主题 3:寻友之旅

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

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


思路:BFS

这道题是经典的图论中的最短路径问题,没有权重为负的边,直接使用BFS即可

  • BFS的实现基于队列这个数据结构,在golang中使用slice即可

    • 入队使用q = append(q, tmp)将元素tmp加入队列尾部

    • 出队使用q = q[1:]将一个元素从队列头部删去

      (记得确保此时队列不为空,否则会报错panic: runtime error: slice bounds out of range

  • 由于我们还要维护距离,这有点类似二叉树的层序遍历,即我们需要保证同一层的节点计算得到的距离都相等,实际代码实现中技巧是

    • 每次进入第一层循环时(第一层循环,结束条件是len(q) != 0),都使用一个变量n来保存这次队列的长度;单次循环结束时保存距离的变量step++

    • 然后进行n次循环(第二层循环,结束条件是while(n--)),每次都将队列中的第一个元素出队(记为top),并将一分钟可以到达的节点入队,即将

      • top+1top+1

      • top1top-1

      • top×2top\times2

      三个节点入队【注意判断上述三个值都在[0,1e5]的范围内】

    • 在这个过程中如果遇到节点dst,即return step,得到最终答案


代码实现