问题描述
小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;
}
}
}