在一根无限长的数轴上,你站在0
的位置。终点在target
的位置。
每次你可以选择向左或向右移动。第 n 次移动(从 1 开始),可以走 n 步。
返回到达终点需要的最小移动次数。
示例 1:
输入: target = 3 输出: 2 解释: 第一次移动,从 0 到 1 。 第二次移动,从 1 到 3 。
示例 2:
输入: target = 2 输出: 3 解释: 第一次移动,从 0 到 1 。 第二次移动,从 1 到 -1 。 第三次移动,从 -1 到 2 。
注意:
target
是在[-10^9, 10^9]
范围中的非零整数。
思路:
这道题可以转化为,给定如下序列+1+2+3+4+...+ k=target,使得满足条件成立的正负号分布,即每个数字前可以是正号,也可以是负号,我们分为以下三步走。
第一步:找到最小的k,使得1到k的累加和sum大于等于target
第二步:计算sum和target的差,如果是偶数,那么把其中一个数前面的符号改为负数即可,因为把第i个数改为负号,所以总和sum减少了2*i
第三步:如果是奇数,那么就一直加,直到差是偶数,这时肯定可以通过改变数字前面的符号为符号得到target
这里简单说明一下:为什么这样得到的k一定是最小的,因为第一步是累加所有的和,都是正数累加,保证到达target或者大于target的数k一定是最小的,这时如果等于target,那么返回k。如果不等于k且差是偶数,也返回k(k也是最小),如果不等于k且差是奇数,最多我们只会加两个数就可以使得差是偶数,否则通过数学是得不到target的,这样也能保证k最小
参考代码:
class Solution {
public:
int reachNumber(int target) {
target = abs(target);
int index = 1,sum=1;
while (sum < target) {
index++;
sum += index;
}
while ((sum - target) % 2 != 0) {
index++;
sum += index;
}
return index;
}
};