当青训营遇上码上掘金
题目
下面是主题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
),并将一分钟可以到达的节点入队,即将三个节点入队【注意判断上述三个值都在
[0,1e5]
的范围内】 -
-
在这个过程中如果遇到节点
dst
,即return step
,得到最终答案
-