1. 程式人生 > >【leetcode】Reach a Number

【leetcode】Reach a Number

target urn infinite break 數組 cond 要求 情況 ...

題目:

You 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.
Example 2:
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.
Note:
target will be a non-zero integer in the range [-10^9, 10^9].

解題思路:

  看完題目後,我腦子裏首先出現的是動態規劃算法解決這一類問題。但是仔細想想,又覺得不太對,首先target的範圍很大,沒有這個大的數組可以保存中間結果。之後腦子裏閃過了無數的方法,但都被一一否決了。萬般無奈之下,想起了“找規律”的老辦法。題目要求是從0開始,第n次操作可以到達target,那麽可以先試試找出每次操作可以到達的的number,是否能夠發現其中的規律。

function unique(a) {
    var res = [];

    for (var i = 0, len = a.length; i < len; i++) {
        
var item = a[i]; for (var j = 0, jLen = res.length; j < jLen; j++) { if (res[j] === item) break; } if (j === jLen) res.push(item); } return res; } var reachNumber = function(target) { var l = [0] for(var i = 1;i < 6;i++
){ var tl = [] while(l.length > 0){ var t = l.pop() tl.push(t-i) tl.push(t+i) } var tl = unique(tl).sort(function(a,b){ return a-b}) //console.log(i,‘:‘,tl[0],tl[1],tl[2],tl[3]) console.log(i,‘:‘,tl) for(var j =0;j<tl.length;j++){ l.push(tl[j]) } } }; reachNumber()

輸出的結果如下:

1 ‘:‘ [ -1, 1 ]
2 ‘:‘ [ -3, -1, 1, 3 ]
3 ‘:‘ [ -6, -4, -2, 0, 2, 4, 6 ]
4 ‘:‘ [ -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10 ]
5 ‘:‘ [ -15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15 ]

為了控制輸出的長度,這裏設置了i<6的條件,其實適當把i放大,會發現更明顯的規律。

這裏就直接把規律列出來了:

a. 第n次操作能到達的最大範圍是 -(1+2+...+n)和 (1+2+...+n);

b. 負數的number和正數的number是對稱的,可以令target = abs(target);

c. n%4 == 0或者n%4 == 3的時候,只能移動到小於偶數的number;

d. n%4 == 1或者n%4 == 2的時候,只能移動到奇數的number;

所以,要找出最小的n,可以到達abs(target)分兩種情況:

1. abs(target)是偶數,需要滿足上面的a和c兩個條件;

2.abs(target)是奇數,需要滿足上面的a和d兩個條件;

代碼如下:

var reachNumber = function(target) {
    if (target < 0){
        target = -target
    }
    if(target == 1 || target == -1){
        return 1
    }
    var isOdd = target%2
    var count = 1;
    var t = 1;
    while(count++) {
        t += count
        if (t >= target && isOdd == 0 && (count % 4 == 3 || count % 4 == 0)) {
            return count;
        }
        else if (t >= target && isOdd != 0 && (count % 4 == 1 || count % 4 == 2)) {
            return count
        }

    }
};

console.log(reachNumber(1))

【leetcode】Reach a Number