marscode刷题记录-39计算从位置x到y的最小步数

86 阅读1分钟

39计算从位置x到y的最小步数

问题描述

小F正在进行一个 AB 实验,需要从整数位置 x 移动到整数位置 y。每一步可以将当前位置增加或减少,且每步的增加或减少的值必须是连续的整数(即每步的移动范围是上一步的 -1+0 或 +1)。首末两步的步长必须是 1。求从 x 到 y 的最少步数。

输入描述

输入包含两个整数 x 和 y,表示起始位置和目标位置。

输出描述

输出从 x 到 y 所需的最小步数。

思路

这个问题一开始想到的是贪心的思想,就是尽可能的走最大的步数,也就是1,2,3...n...3, 2, 1 这样,也就是我们一开始走1, 接着走2 如果剩下的步数小于我们要走的步数,那么说明我们就走完了,如果大于我们要走的步数,那么步数还需要+2。 代码的时间复杂度是 O(sqrt(n)),其中 n 是 |x - y|

int solution(int x_position, int y_position) {
  // Please write your code here
  int ans = 0;
  int delta = abs(x_position - y_position);
  int current_step = 1;
  while(delta > 0) {
    if(delta > current_step) {
       ans += 2;
       delta -= 2 * current_step;
       current_step++;
    } else {
      ans += 1;
      break;
    }
  }
  return ans;
}

进一步的思路

那有没有办法更快一点呢?当然是有的,我们注意到其实答案就在 2 * sqrt(n) - 1 到 2 * sqrt(n) + 1之间,所以我们直接通过开放求解该问题

int solution(int x_position, int y_position) {
  // Please write your code here
  int delta = abs(x_position - y_position);
  if(delta == 0) return 0;
  
  int k = sqrt(delta);
  if(k * k == delta) {
    return 2 * k - 1;
  } else {
    if(delta - k * k <= k) {
      return 2 * k;
    } else {
      return 2 * k + 1;
    }
  }
}