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

126 阅读2分钟

当青训营遇上码上掘金

第五届字节跳动青训营开始啦~ 让我们一起快乐写码赢青训营青豆吧!

主题:寻友之旅

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

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

代码-迪杰斯特拉算法

废话不多说,先上代码,再做解释

思路

首先看到题,乍一看这是一道和“爬楼梯”很相似的题目,但是这道题也可以看作一道最短路径题目,所以可以用迪杰斯特拉算法。

每条边的权值为1(分钟),边的to 和 from 分别是当前节点和 X-1,X+1, X*2

  • 准备:首先,我们需要一个 open 表,一个 close 表,open表需要是一个 HashMap<int,int>,map的key是边的 from节点, map的value是从n到 from 节点所用的时间,close表可以直接是一个set 当走到 k 的时候直接返回,不需要记住所有节点的最短路径。

  • 初始化:初始化需要把 n = 0放入 open表,把 -1 放入close表(防止后退浪费时间)

  • 循环:如果open表不为空就一直走下去,实际上在这道题里这就是一个死循环,因为边集没有设置,就是无穷个边,循环需要做的就是不断地从open表找到一个时间最短的节点,把当前节点拿出open表,放入close表,然后更新open表(如果当前节点走到下一节点用的时间比open表记录的时间短,就修改,open表不存在可以看作用的时间是+∞)

  • 结束条件:当走到k节点的时候结束循环