Reach a Number 到达终点数字

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

猜你喜欢

转载自blog.csdn.net/qq_26410101/article/details/84331877