这是我在掘金的第一个文章,写得不好还请见谅。
首先来看青训营的第三个题目:
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
首先我们可以简化题目,就是从一个点到另一个点的最短移动距离,且只能通过向前1步、向后1步、或移动两倍的部署三种来移动,因此我们可以再简化成一个一维数组来表述运动的路径和状态。
再看,题目求的是最快到达时间,也就是说是求最短距离,分析一下,有最短距离就肯定不存在环路,在一维数组的理解就是只能经过这个格子一次,也就是除了初始化最多只能存放一次数据;同时,也就意味着,只要第一次得到的结果与终点相同,则说明至少当前就是一个最优解。
分析一下,我们可以发现,通过使用队列来存放当前的位置的同时,也可以间接的记录了步数,因为只要不是终点,就会被插入队列,相当于步数会一步一步的不断上升,通过队列和BFS的思想便可以实现本题目的要求。因此本题的考点便时使用队列完成BFS的搜索。
梳理完上面的思路,接下来就是实现代码了。
import java.util.*;
public class test {
static int n;
static int k;
static final int N = 100010;
private static int bfs() {
int[] dist = new int[N];
Queue<Integer> queue = new LinkedList<>();
Arrays.fill(dist, -1);
queue.add(n);
dist[n] = 0;
while (!queue.isEmpty()) {
int t = queue.poll();
if (t - 1 >= 0 && dist[t - 1] == -1) {
dist[t - 1] = dist[t] + 1;
if (t - 1 == k) return dist[t - 1];
queue.add(t - 1);
}
if (t + 1 >= 0 && dist[t + 1] == -1) {
dist[t + 1] = dist[t] + 1;
if (t + 1 == k) return dist[t + 1];
queue.add(t + 1);
}
if (t * 2 < N && dist[t * 2] == -1) {
dist[t * 2] = dist[t] + 1;
if (t * 2 == k) return dist[t * 2];
queue.add(t * 2);
}
}
return -1;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
k = sc.nextInt();
System.out.println(bfs());
}
}
就这样,小青就走过了一个寻友之旅到达了小码家,但是我借鉴了小青的寻友之旅还是找不到另一半……