Reach a Number 到達終點數字

麥田裡的哈士奇發表於2018-11-21

在一根無限長的數軸上,你站在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;
    }
};

 

 

相關文章