当青训营遇上码上掘金,那我们就要开始做题了(悲)
主题 3:寻友之旅
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
我的代码如下:
import java.util.Queue;
public class Main {
public static void main(String[] args) {
int n = 3;
int k = 11;
int result = findShortestTime(n, k);
System.out.println(result);
}
private static int findShortestTime(int n, int k) {
if (n >= k) {
return n - k;
}
int[] time = new int[100001];
boolean[] visited = new boolean[100001];
Queue<Integer> queue = new LinkedList<>();
queue.offer(n);
visited[n] = true;
while (!queue.isEmpty()) {
int current = queue.poll();
if (current == k) {
return time[k];
}
if (current - 1 >= 0 && !visited[current - 1]) {
queue.offer(current - 1);
visited[current - 1] = true;
time[current - 1] = time[current] + 1;
}
if (current + 1 <= 100000 && !visited[current + 1]) {
queue.offer(current + 1);
visited[current + 1] = true;
time[current + 1] = time[current] + 1;
}
if (current * 2 <= 100000 && !visited[current * 2]) {
queue.offer(current * 2);
visited[current * 2] = true;
time[current * 2] = time[current] + 1;
}
}
return -1;
}
}
当我看到这道题时,我立即意识到这是一个典型的最短路径问题。这里有两种移动方式:步行和公交,因此我们需要使用一个搜索算法来找到从起点n到终点k的最短路径。根据题目描述,我们可以使用广度优先搜索算法来解决这个问题。
解题步骤如下:
- 创建一个time数组来记录到达每个节点所需的时间,初始化为0。
- 创建一个visited数组来记录哪些节点已经被访问过,初始化为false。
- 创建一个队列queue,将起点n入队。
- 将n标记为visited。
- 从队列中取出第一个节点current。
- 如果current等于终点k,返回time[k]。
- 尝试所有可能的移动方式:向左走、向右走和乘坐公交,将未访问的节点入队。
- 标记新节点为visited。
- 设置新节点的time为当前节点的time加1。
- 如果队列不为空,则回到步骤5,否则返回-1,表示无法从起点到达终点。
- 返回time[k],获取最短时间。
通过这个算法,我们可以找到从起点n到终点k的最短路径。算法的时间复杂度为O(N),其中N为路径图中的节点数量,因为每个节点最多只会被访问一次。
总的来说,该函数使用广度优先搜索算法,从起点n开始,尝试所有可能的移动方式,并遍历整个路径图,直到到达终点k。在搜索过程中,使用一个time数组来记录到达每个节点所需的时间,并使用一个visited数组来记录哪些节点已经被访问过。最后返回time[k]来获取最短时间。
需要解释的是,广度优先搜索(BFS)是一种常见的图搜索算法,用于在非加权图或加权图的所有边权相等的情况下找到从起点到终点的最短路径。
BFS从起点开始,将起点放入一个队列中,然后迭代地将队列中的节点一个一个取出来,对于每个取出的节点,找到它的所有邻居节点,并将这些邻居节点加入到队列中。
由于队列是先进先出的数据结构,因此可以保证按照从起点到终点的距离依次遍历节点,直到找到终点为止。因此,当我们找到终点时,BFS保证我们已经找到了最短路径,因为我们先访问了距离起点1个单位的所有节点,然后是距离起点2个单位的所有节点,以此类推,直到我们找到终点。由于BFS遍历每个节点一次,因此时间复杂度为O(N),其中N为路径图中的节点数。
在本题中,我们使用的就是BFS算法来搜索从起点n到终点k的最短路径,以找到小青最快到达小码家的时间。