当青训营遇上码上掘金
主题 3:寻友之旅
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
题目分析
从n移动到k 有三种方式 前进,后退,公交
根据题目分析这是一道最短路径问题,使用BFS 可以解决
因为n 和 k 的关系不确定我们需要进行讨论
- 若 n > k 只能后退步行,所需时间为 n-k
- 若 n <= k 从 n 开始出发 将 n 加入队列当中
- 取队列列首所在位置 p
- 若 p < k 两种前进可能 1.步行前进1步 2.公交前进
- 分别更新这两种情况下的p 若p未被访问将其加入队列当中
- 若 p > k 只能后退步行 更新 p 若p未被访问将其加入队列当中
- 重复3-6 直至 队列为空 或者 p==k
- 最终返回的结果为更新p的次数
从正向推导在一定时间内能访问的位置,确保了访问该位置的最短时间
当时也考虑是否可以使用动态规划进行解决,由于涉及到反向回退再次更新,我确实没有找到合适的方式去解决,最终还是采用bfs进行计算。
实现
这里使用的是c++ 语言,采用queue 队列数据结构。关于访问节点的记录我才用set 数据结构进行存储,这里使用数组也是可以的但是空间开辟需要200002 空间进行记录,这里需要考虑2倍之后回退的问题。
该算法的时间复杂度O(n) 访问结点的个数
代码
小结
整个解题思路和实现见上文,欢迎大家相互交流批评指正