在一根无限长的数轴上,你站在0
的位置。终点在target
的位置。
你可以做一些数量的移动 numMoves
:
- 每次你可以选择向左或向右移动。
- 第
i
次移动(从 i == 1
开始,到 i == numMoves
),在选择的方向上走 i
步。
给定整数 target
,返回 到达目标所需的 最小 移动次数(即最小 numMoves
) 。
示例 1:
输入: target = 2
输出: 3
解释:
第一次移动,从 0 到 1 。
第二次移动,从 1 到 -1 。
第三次移动,从 -1 到 2 。
示例 2:
输入: target = 3
输出: 2
解释:
第一次移动,从 0 到 1 。
第二次移动,从 1 到 3 。
提示:
-109 <= target <= 109
target != 0
Related Topics
👍 180👎 0
数学分析计算
如图
- 假设从左往右走了
k
次到达M
点刚好越过或者达到target
点,即k(k+1)/2 ≥ target
- 那么我们即需要再这之前往反方向移动距离为
D
- 又,因为反向移动了,仍需掉头继续往这个方向移动,即假设我们往反向移动了的距离为
x
- 那么我们就有了
2x = D
这样的结果,即反向移动加折回到原点0
的距离就是我们原先应当到达M
点,因为折返损耗了距离D
而只能达到位置target
的情况 - 即有,
x = D/2
,那么我们知道D
必然需要为一个偶数,因为x
必然是一个整数
举个简单的例子
target = 8
那么我们知道 k = 4
的时候,能到达M
点位置为10,测试相差距离D
为2,即需要往反向移动x = D/2 = 1
距离,那么我们就知道应当按照- 1 + 2 + 3 + 4 = 8
的方法运行
代码
class Solution {
public int reachNumber(int target) {
if (target==0)return 0;
target = Math.abs(target);
int k = (int) Math.sqrt(2 * target);
k--;
while ((1 + ++k) * k / 2 < target){}
int d = (1 + k) * k / 2 - target;
while (d%2!=0) {
d += ++k;
}
return k;
}
}
发表评论