初入青训营 | 寻友之旅

62 阅读1分钟

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

题目

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

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

解题思路

  • 我们通过题目可以发现N的值是不会变为负数的,因为变为负数之后,我们只有进行N=N+1操作才能再次变为正数,这样就导致花费的时间变长
  • 如果在N>K的情况下,我们只需要通过-1操作就能得到结果;如果是N<K的情况,我们可以通过三种方式组合的方法来得到结果
  • 小青是一定可以到达小码所在位置的,也就是说该题目一定是有解的,因为最坏的情况下我们可以通过+1或者-1得到结果
  • 由于该题目是求最短时间,所以考虑使用BFS算法实现。通过visit数组来判断一个结点是否已经走过。用Node类来存放路径的值以及花费的时间,使用带参构造函数来加入结点。需要注意的是在加入新的结点的时候,要判断该结点是否走过
  • 每次移动共有三种状态,三种状态的操作值都是1,按三种操作层次搜索,当优先搜索到目标值,直接返回结果即可,BFS搜索每次都是优先最短距离进行搜索

代码实现

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {
    static int k;
    static int[] visit = new int[1000000];
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //输入当前位置
        int n = sc.nextInt();
        //输入目标位置
        k = sc.nextInt();
        sc.close();
        System.out.println(BFS(n));
    }

    public static int BFS(int n) {
        Node next;
        Node head = new Node(n,0);

        Queue<Node> queue = new LinkedList<>();
        //把head元素插入队列
        queue.offer(head);
        //在visit数组中把走过的元素设置为1
        visit[head.x]=1;

        //当队列不为空时进行循环,如果队列为空则停止循环
        while(!queue.isEmpty()) {
            //取出队列第一个元素赋值给next
            next=queue.poll();
            //num表示当前位置
            int num=next.x;
            //若当前位置等于目标位置,返回需要的步数
            if(num== k) {
                return next.step;
            }
            else {
                //若当前位置不等于目标位置
                //遍历当前位置的结点
                int a=num+1,b=num-1,c=num*2;
                if(a>=0 && a<=100000 && visit[a]==0) {
                    //把当前结点插入队列
                    queue.offer(new Node(a,next.step+1));
                    //在数组中把当前位置的元素设置为1
                    visit[a]=1;
                }
                if(b>=0 && b<=100000 && visit[b]==0) {
                    queue.offer(new Node(b,next.step+1));
                    visit[b]=1;
                }
                if(c>=0 && c<=100000 && visit[c]==0) {
                    queue.offer(new Node(c,next.step+1));
                    visit[c]=1;
                }
            }
        }
        return 0;
    }
}

class Node{
    /**
     * 小青当前的位置
     */
    int x;
    /**
     * 小青到达x所需的步数
     */
    int step;

    Node(int x,int step){
        this.x=x;
        this.step=step;
    }
}

个人总结

希望青训营能充实我的寒假生活,提升我的专业技术水平,一起加油吧!