754. Reach a Number

ou are standing at position 0 on an infinite number line. There is a goal at position target.

On each move, you can either go left or right. During the n-th move (starting from 1), you take n steps.

Return the minimum number of steps required to reach the destination.

Example 1:

Input: target = 3
Output: 2
Explanation:
On the first move we step from 0 to 1.
On the second step we step from 1 to 3.

Input: target = 2
Output: 3
Explanation:
On the first move we step from 0 to 1.
On the second move we step  from 1 to -1.
On the third move we step from -1 to 2.

找到达到目标点最小步数,第n步移动的距离为n,往左或往右都可以。

这是一个偶函数,走到target和-target都是一样的,所以只考虑target>0的情况。

1、如果能有n,使得sum = 1+2+...+n-1+n = target,显然,这是最佳方案。

2、如果sum > target,需要前面有反方向走的

2.1、delta = (sum - target) 是偶数,设第i,j...步往反方向走,那么最后到达的距离是: sum - 2*(i+j+...),其中i, j...∈[1, n],由于delta是偶数,必定存在i,j,...,使得2*(i+j+...) = delta。所以这种情况下,最佳步数还是n。

2.2、delta = (sum - target) 是奇数,这样2.1情况下的i, j...找不到,需要加步数。所以最后到达的距离是: sum - 2*(i+j+...) + n+1 + n+2 +...+ n+k ,现在需要找出最小的k。显然,k需要满足的条件是:使 sum + n+1 + n+2 +...+ n+k - delta 为偶数,即 n+1 + n+2 +...+ n+k 为奇数,这样就能找到符合条件的i,j,...。所以,当n是偶数时,n+1就是奇数,只需要加1步;否则,加2步。

class Solution {
public:
    int reachNumber(int target) {
        int n = 0;
        int sum = 0;
        target = abs(target);
        while (sum<target) {
            ++n;
            sum += n;
        }

        if ((sum-target)%2==0)
            return n;
        else {
            if (n%2==0)
                return n+1;
            else
                return n+2;
        }
    }
};

 

posted @ 2018-01-06 20:31  Zzz...y  阅读(1105)  评论(0编辑  收藏  举报