寻友之旅

95 阅读3分钟

当青训营遇上码上掘金

主题 3:寻友之旅

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

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

解题过程

对于这道题目,相当于求俩点之间的最短路径,并且给出了俩俩之间的位置关系,所以很容易想到可以使用Dijkstra最短路径算法求N点到K点的最短时间,又因为俩俩联系的位置进行移动时间都是1个单位,所以使用Dijkstra最短路径算法的时间复杂度和广度优先算法复杂度是一样的,所以呢我就直接用广度优先暴力开解这道题,代码如下:

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

public class aa {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int N=scanner.nextInt();
        int K=scanner.nextInt();
        System.out.println(people(N,K));
        return;
    }

    static int people(int a, int b){
        if (a >= b) {
            return a - b;
        }
        int m[][]=new int[200000][2];
        m[a][0] = 1;
        Queue<Integer>queue = new LinkedList<>();
        queue.add(a);
        int c;
        while(!queue.isEmpty()){
            c=queue.poll();
            if(c==b){
                break;
            }
            m[c][0] = 1;
            if (c>1&&m[c-1][0] == 0){
                m[c-1][0] = 1;
                queue.add(c-1);
                m[c-1][1] = m[c][1]+1;
            }if (m[c+1][0] == 0){
                m[c+1][0] = 1;
                queue.add(c+1);
                m[c+1][1] = m[c][1]+1;
            }if (2*c<100000&&m[2*c][0] == 0){
                m[2*c][0] = 1;
                queue.add(2*c);
                m[2*c][1] = m[c][1]+1;
            }
        }
        return m[b][1];

    }
}
  • 准备工作,先创建一个数组m,其中用m[n][0]=1作为标记,记录点n已经遍历过,避免重复的搜索,m[n][1]表示小青到n点的最短时间。并建立一个队列用于广度优先搜索。
  • 将小青的位置加入队列中
  • 从队列中取出元素c,根据数组m[n][0]判断位置c-1,c+1,2*c三个位置是否被遍历过,并且三个值的范围在1-10000
  • 若没被标记,则标记该位置,并记录该位置最短时间即m[c][0]+1于数组m[n][1]中
  • 进行下次遍历,从队列中取出值,重复上述步骤
  • 当取出值为小码位置时结束遍历,输出m[b][1],即为最短时间

小小总结一下:这种类型题目一般就是使用最短路径,广度优先,深度优先,动态规划这些常见的方法,这题我也想过又动态规划是不是会降低一点时间复杂度,但是由于小青可以往后走,后面的位置结果也会影响前面的位置的结果,所以感觉应该是不太合适,最后只能用这种暴力开解的方法了,应该是会有更好的方法,实在想不到了~