[Leetcode學習-c++&java]Reach a Number
問題:
難度:medium
說明:
假設你有一個無限座標軸,然後你 第 N 步 可以一次移動 N 個位置(從 1 開始),給出一個座標 T,求最少多少步可以移動到座標 T。
題目連線:https://leetcode.com/problems/reach-a-number/
輸入範圍:
target
will be a non-zero integer in the range[-10^9, 10^9]
.
輸入案例:
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.
我的程式碼:
數學題,如果用 bfs 肯定空間都爆了,畢竟是 空間佔用 指數增長。
1、
假設走 N 步到達,那麼其中有 K 步反著走是最短行程
假設輸入數字為 T,最少需要 N 步到達 T,如果 N 步都正向望著 T 走,那麼從 0 到 第 N 步長度為 SUM = N * (N + 1) <<1
那麼如果我其中第一步反著走,從 0 到 第 N 步長度為 SUM - (1 << 1),我第 K 步反著走就是SUM - (K<< 1)
那麼某幾步反著走就是SUM - ((K1 + K2 + K3 + .....) << 1) =SUM - (ΣK<< 1)
2、
把輸入負數都弄成正數,因為走路的邏輯一致。
SUM >= T,所以N * (N + 1) <<1 >= T
得出:N^2 + N - 2T >= 0 (一元二次方程)
根據一元二次方程求根得: (N1必定是正數)
3、
從 N1 開始搜尋,因為 N1 開始才能獲得 SUM >= T
有 SUM - T = X = (K << 1),因為存在SUM - (K<< 1) =T
所以 K = SUM - T >> 1,如果 SUM - T 是奇數就跳過,不存在 SUM - T 為奇數
那麼第 N 步是到達 T的步數,只要有 N + N - 1 >= K 就肯定包含 K1 K2 K3 ...的一個集合,滿足 K = SUM - T(為什麼剛好 N + N - 1我忘了)
4、
所以比較爽的一道題可以用數學公式搞定
JAVA:
class Solution {
public int reachNumber(int target) {
long t = (long)Math.abs(target);
int begin = (int)Math.ceil((Math.ceil(Math.sqrt(8 * t + 1)) - 1) / 2);
for(int i = begin;;i ++) {
int sum = (int)((i * (i + 1) >> 1) - t);
if((sum & 1) == 0) {
sum >>= 1;
if(i + i - 1 >= sum) return i;
}
}
}
}
C++:
class Solution {
public:
int reachNumber(int target) {
long t = (long)abs(target);
int begin = (int)ceil((ceil(sqrt(8 * t + 1)) - 1) / 2);
for(int i = begin;;i ++) {
int sum = (int)((i * (i + 1) >> 1) - t);
if((sum & 1) == 0) {
sum >>= 1;
if(i + i - 1 >= sum) return i;
}
}
}
};