当青训营遇上码上掘金之寻友之旅

87 阅读3分钟

当青训营遇上码上掘金

此次分享的主题为Java版本的寻友之旅。码上掘金链接🔗:code.juejin.cn/pen/7194977…


主题 3:寻友之旅

小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)

请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)

灵感思路

这个场景有点像是走迷宫,寻找最短的路径,对于类似这种找最短时间、最短路径的问题,一般采用广度优先搜索的方法,也就是常说的 BFS。对于 BFS 来讲,每走下一步,即每过一分钟,都可以将其所有可能的到达位置记录下来,这样就不会出现错过最早到达时间的情况,从最初就记录了小青可以到达的所有位置。

因为小码的位置是固定的,不需要进行移动,这样的话,只需要找出小青移动可以到达的位置即可,当小青到达的位置与小码所处的位置相同时,即可得到最终时间,停止后续操作。

我们可以使用一个队列来记录小青所到达的所有位置,初始状态下,将小青所在位置入队,将时间加一,然后将上一分钟所在位置出队,根据该位置去判断小青下一步可到达的位置是否与小码所在位置相同,若相同,则输出答案,否则,我们需要考虑三种情况,将三种可到达位置分别入队,重复以上操作,直到小青可到达位置包含小码所在位置。

我们还要考虑一种特殊情况,若小青和小码所处的初始位置相同,则小青不需要时间来移动,直接输出答案 0 即可。

题解方法

public class Main {
   public static void main(String []args) {
      Scanner sc = new Scanner(System.in);
      int n = sc.nextInt();
      int k = sc.nextInt();
      int time = 0;
      if(n == k) {
        System.out.println(time);
        return;
      }
      Queue<Integer> queue = new ArrayDeque<>();
      queue.offer(n);
      while(!queue.isEmpty()) {
        time++;
        for(int i = 0; i < queue.size(); i++) {
          int t = queue.poll();
          if(t + 1 == k || t - 1 == k || t * 2 == k) {
            System.out.println(time);
            return;
          }
          queue.offer(t + 1);
          queue.offer(t - 1);
          queue.offer(t * 2);
        }
      }
   }
}

如果你有其他的思路或者更好的解法,亦或者你发现了文章出现了错误或有不足,欢迎在评论区和我交流,我看到了一定会回复。

写文章不易,如果你觉得文章对你有帮助,麻烦点一下点赞、收藏,你的支持是我写文章的最大动力!