当青训营遇上码上掘金
第五届字节跳动青训营开始啦~ 让我们一起快乐写码赢青训营青豆吧!
主题:寻友之旅
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 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节点的时候结束循环