小F正在进行一个 AB 实验,需要从整数位置 x 移动到整数位置 y。每一步可以将当前位置增加或减少,且每步的增加或减少的值必须是连续的整数(即每步的移动范围是上一步的 -1,+0 或 +1)。首末两步的步长必须是 1。求从 x 到 y 的最少步数。
输入描述
输入包含两个整数 x 和 y,表示起始位置和目标位置。
输出描述
输出从 x 到 y 所需的最小步数。
测试样例
样例1:
输入:
x_position = 12, y_position = 6
输出:4
样例2:
输入:
x_position = 34, y_position = 45
输出:6
样例3:
输入:
x_position = 50, y_position = 30
输出:8
样例4:
输入:
x_position = 0, y_position = 0
输出:0
解题思路
-
计算距离:首先计算从
x到y的绝对距离distance = |y - x|。 -
步数计算:
-
如果
distance为0,则不需要移动,步数为0。 -
如果
distance为1,则只需要一步,步数为1。 -
对于其他情况,步数可以通过以下公式计算:
- 步数
steps = 2 * k - 1,其中k是满足k * (k + 1) / 2 >= distance的最小整数。 - 这个公式基于一个事实:每一步的步长是连续整数,且首末步长为
1,可以通过数学归纳法推导出。
- 步数
-
代码public class Main {
public static int solution(int xPosition, int yPosition) {
int distance = Math.abs(yPosition - xPosition);
if (distance == 0) {
return 0;
}
int k = 1;
while (k * (k + 1) / 2 < distance) {
k++;
}
return 2 * k - 1;
}
public static void main(String[] args) {
// You can add more test cases here
System.out.println(solution(12, 6) == 4);
System.out.println(solution(34, 45) == 6);
System.out.println(solution(50, 30) == 8);
}
} 步数公式 `2 * k - 1的推导公式:
问题分析
我们需要计算从位置 x 移动到位置 y 的最少步数,每一步的步长是上一步的 -1,+0 或 +1,并且首末两步的步长必须是 1。
数学推导
- 首末步长为1:这意味着第一步和最后一步的步长必须是
1。 - 连续整数步长:每一步的步长必须是上一步的
-1,+0或+1。
步数计算
假设我们需要移动的总距离为 distance,我们可以通过以下步骤来推导步数公式:
-
步长序列:
- 第一步:
1 - 第二步:
2 - 第三步:
3 - ...
- 第
k步:k
- 第一步:
-
步长和:
- 这些步长的和可以表示为
1 + 2 + 3 + ... + k = k * (k + 1) / 2。
- 这些步长的和可以表示为
-
步数公式:
- 我们需要找到最小的
k,使得k * (k + 1) / 2 >= distance。 - 一旦找到这个
k,步数就是2 * k - 1。
- 我们需要找到最小的
是 2 * k - 1的原因:
-
首末步长为1:
- 第一步和最后一步的步长都是
1,所以这两步已经占据了2步。
- 第一步和最后一步的步长都是
-
中间步长:
- 中间的步长可以是
1, 2, 3, ..., k-1,这些步长的和是(k-1) * k / 2。
- 中间的步长可以是
-
总步数:
- 总步数 = 首末步长 + 中间步长 =
2 + (k-1) = 2 * k - 1。
- 总步数 = 首末步长 + 中间步长 =