編程數學思維

754. 到達終點數字

難度中等101

在一根無限長的數軸上,你站在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:首先x與-x的答案是一樣的,只是在對1 2 3 ....n中的n-1個位置加正負號是完全相反的而已,因此可以統一爲正數;然後就可以採用BFS的方式搜索整個解答樹,借用BFS能夠搜索最短路徑的特點得到答案。問題:層次過深的時候會導致隊列過大,所以無論是時間還是空間複雜度都挺令人堪憂的。

思維2:純數學解法。首先我們設k是滿足下式的最小正整數:

                                                           S=1+2+...+k=\frac{k(k+1)}{2}>=target

分情況討論:

1.取等於的情況,毫無疑問,答案就是k

2.取大於的情況:我們知道當我們將一個整數x變-x並加上它的時候,我們的數會相較原來少掉2*x,所以這裏需要討論多出來的部分是奇數還是偶數的情況

        A.若爲偶數,首先我們根據對k的假設可以知道:

                      1+2+...+k-1=\frac{(k-1)k}{2}<target

                     S=1+2+...+(k-1)+k=\frac{k(k+1)}{2}>target

              所以必有結果:

                     S-target<k

然而在考慮k之前,我們已經考慮過所有小於k的數。設S-target=x,因爲x<k且x%2==0,所以x/2必定是整數且屬於[1,k],直接取反即可,此時只用到了k個數。

         B.若爲奇數,那麼我們設多餘的部分爲x,而我們考慮的數裏包括了x-1,我們直接將x-1取反,這樣多餘的部分就只剩下1了,再來看k

                   1)k爲奇數,那麼通過1+k+1-(k+2)使得多餘部分爲0。

                   2)k爲偶數,那麼通過1+k+1得到新的多餘部分爲偶數,有下式:

                                     \frac{1+k+1}{2}=1+\frac{k}{2}<=k

                        當且僅當k>=2時成立,此時讓1+k/2對應的數值取反即可。[至於k=1,已經在第一種大情況下考慮過啦 ovo ]

代碼1:

class Solution {
public:
    int reachNumber(int target) {
        if(target<0)target=-target;
        int k=0,upBound=0;
        while(upBound<target){
            upBound+=++k;
        }
        return upBound==target?k:(((upBound-target)&1)?k+1+(k&1):k);
    }
};

代碼2:(使用sqrt需要處理一些邊界問題,因爲浮點強轉爲int小數會直接截斷)

class Solution {
public:
    int reachNumber(int target) {
        if(target<0)target=-target;
        int k=sqrt(target<<1),upBound=k*(k+1)/2;
        if(upBound<target){
            ++k;
            upBound=k*(k+1)/2;
        }
        return upBound==target?k:(((upBound-target)&1)?k+1+(k&1):k);
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章