当青训营遇上码上掘金
主题三 - 寻友之旅
题目描述:
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
- 步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
- 公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
思路:
这个问题可以再抽象一下,把一分钟看作是走一步,移动节点的长度看成一步迈出去的步长,那么这道题就变成了求小青到小码的最短步数,这样看是不是想到了经典的 BFS 模型,广度优先搜索逐层扩展,扩展次数就是最短步数,直接把 BFS 模板搬过来就搞定了。
宽度优先搜索算法(又称广度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。
Java 代码:
import java.util.LinkedList;
import java.util.Queue;
public class Solution {
final static int MAX_LEN = (int) 1e5;
static class Node {
int position;
int step;
Node(int position, int step) {
this.position = position;
this.step = step;
}
}
public int bfs(int n, int k) {
if (n == k) return 0;
Queue<Node> que = new LinkedList<>();
que.add(new Node(n, 0));
while (!que.isEmpty()) {
Node curr_node = que.poll();
if (curr_node.position == k)
return curr_node.step;
if (curr_node.position + 1 <= MAX_LEN)
que.add(new Node(curr_node.position + 1, curr_node.step + 1));
if (curr_node.position - 1 <= MAX_LEN)
que.add(new Node(curr_node.position - 1, curr_node.step + 1));
if (curr_node.position * 2 <= MAX_LEN)
que.add(new Node(curr_node.position * 2, curr_node.step + 1));
}
return -1;
}
}
Node 节点用来存储小青当前的位置以及走的步数(分钟),先将初始位置加入队列,只要队列不为空,就取队首元素向 +1,-1,*2 这三个位置扩展,直到遇到小码。