124、到达终点数字

题目描述
在一根无限长的数轴上,你站在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]范围中的非零整数。
首先暴力搜索是肯定超时的,因此肯定是有某种技巧在里面的:
这里的移动次数和数字的正负是无关的,因此都用正数来表示,计算第n个时此时1+2+3+…+n>=target,如果前者等于target那么毫无疑问就是n,那么如果前者之和大于target,并且前者减去target为偶数的话,那么也是n,为什么呢?因为如果是偶数,并且这个偶数肯定小于n,那么在其中一步可以向反方向移动一次,比如我向左移动一次和一开始向右移动一次,这样一来一回就差了2,同样的如果是2,一来一回就是4,因此如果二者之差为偶数,也是n
但是如果二者之差是奇数那么就有点复杂了:那么需要判断下一步是奇数还是偶数即n是偶数还是奇数,要往第一步上面去靠,如果n是奇数,那么下一步是偶数,需要到下下一步二者之差才是偶数,偶数的话就是n,那么总共就是n+2,如果n是偶数,n+1是奇数,那么n+1步和target就是偶数,那么就是n+1步
代码

class Solution {
    public int reachNumber(int target) {
     int count = 0;
		target = Math.abs(target);
		
		while ((count*(count + 1)) /2 < target) {
			count ++;
		}
		int tem = (count*(count + 1)) /2 ;
		if((count*(count + 1)) /2 == target){
			return count;
		}
		if((tem - target)%2 == 0){
			return count;
		}
		if(count % 2 == 0){
			return count+1;
		}else {
			return count+2;
		}   
    }
}

排名靠前的代码,利用求根公式直接得出n之后采用根运算来判断是否是偶数

class Solution {
    public int reachNumber(int target) {
        target = Math.abs(target);
        int n = (int)Math.ceil((-1.0 + Math.sqrt(1 + 8.0 * target)) / 2);
        if ((n * (n + 1) / 2) == target)
            return n;
        int d = (n * (n + 1) / 2) - target;
        if ((d & 1) == 0)
            return n;
        return (n & 1) > 0 ? n + 2 : n + 1;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_34446716/article/details/85235353
124