在一根无限长的数轴上,你站在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;
}
}
发表评论