当青训营遇上码上掘金
问题
寻友之旅
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
题解
对于该题目采用广度优先搜索的方式来进行解决,同时对于一些特例进行减枝。
首先,由于题目没有提到 N <= K ,所以存在 N > K 的情况,但是公交车只能往前走,所以当 N > K 的时候可以直接返回 N - K。
而对于 N < K 的情况,考虑到如果当前的位置 cur > 2 * K,那么先回退,再坐公交车,比先坐交车再回退能退的更多。而且因为公交车是2倍的关系,所以可以考虑step的长度为K+2;
这么说可能比较难以理解,举个例子 N = 100, K = 198 那么
- X-1
- 2 * X
即可到达,而
- 2 * X
- X - 1
- X - 1
需要三步才能到达。
所以可以将step设置为K+2来减少step的存储空间。
具体的代码如下所示
import java.util.*;
public class ByteTechCode {
public int byteTechCode(int N, int K) {
if(N >= K){
return N - K;
}
int[] dist = new int[K + 2];
Arrays.fill(dist, -1);
Queue<Integer> que = new LinkedList<>();
dist[N] = 0;
que.add(N);
while(!que.isEmpty()){
int u = que.peek();
if(u == K){
return dist[K];
}
que.poll();
if(u > 0 && dist[u-1] == -1){
dist[u-1] = dist[u] + 1;
que.add(u-1);
}
if(u < K && dist[u+1] == -1){
dist[u+1] = dist[u] + 1;
que.add(u+1);
}
if(2*u < K+2 && dist[2*u] == -1){
dist[2*u] = dist[u] + 1;
que.add(2*u);
}
}
return dist[K];
}
}
class ByteTechCode_test{
public static void main(String[] args) {
ByteTechCode test = new ByteTechCode();
System.out.println(test.byteTechCode(100, 197));
}
}