小青的寻友之旅

199 阅读2分钟

当青训营遇上码上掘金
码上掘金地址:code.juejin.cn/pen/7185528…
题目地址: juejin.cn/post/718775…

题目

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

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

核心代码

// miDistance n为小青位置,k为小码位置,minute为经过的时间
func miDistance(n,k,minute int) int{
  if n == k {
    return minute
  }
  if k >= n && ( n * 2 - k <= k - n ) {
    minute = miDistance(n * 2, k , minute + 1)
  }else {
    if k > n {
      minute = miDistance(k , k , minute + (k - n))
    }else {
      minute = miDistance(k , k , minute + (n - k))
    }
  }
  return minute
}

代码讲解

设小青的位置为k,小码的位置为n

小青寻找小码有两种行走方法,一种是2*n跳跃式行走,但不能回头,另一种为n+1逐步式行走,但可以回头,两种方法消耗的代价相同.

可以轻易看出最快的寻找方法就是先跳跃式,到无法靠跳跃式到达的时刻且最近再逐步式寻找.

此时有一个问题,那就是跳跃式到达的时刻哪一个是最近的,是否要跳越过一次小码的位置,是从小码后面向前走近还是从小码前面向走后近,此时必须进行一次判断, n * 2 - k <= k - n,n * 2 为跳跃后的小青位置,n * 2 - k 就是跳跃后小青位置距离小码位置的距离,k - n为跳跃前小青位置距离小码位置的距离,如果跳跃后的距离小于跳跃前的,就必须进行跳跃,才能得到进行的最短时间.

于是有,k >= n && ( n * 2 - k <= k - n ),判断本次行走是否跳跃,如果是就跳跃,否则不进行跳跃.

对于逐步行走,不必进行多次调用,直接加上小青距离小码的距离即可,因为消耗的时间数和行走的距离相同,注意距离为正数