那么前进的值为
1
+
2
+
3...
+
n
=
(
n
+
1
)
∗
n
/
2
1+2+3...+n = (n + 1) * n / 2
1+2+3...+n=(n+1)∗n/2,当该值sum >= target时,我们停止前进,此时我们可以看出sum值比target大,差值为sum-target,当sum-target为偶数时,那么我们直接让前面某一步值为(sum-targte) / 2改为向后退,那么最后sum值就会减少sum-target。
若sum - target为奇数,那么再前进一步或者两步必然会让sum-target变为偶数。
若n为偶数,那么n+1为奇数,那么只用前进一步,sum-target为偶数
若n为奇数,那么前进两步后,sum-target变为偶数
对于n的寻找可以使用二分查找
时间复杂度:
O
(
l
o
g
n
)
O(logn)
O(logn)
空间复杂度:
O
(
1
)
O(1)
O(1)
classSolution{publicintreachNumber(int target){if(target <0) target =-target;int l =1, r = target;while(l < r){int mid =(l + r)/2;if((1+(long)mid)* mid /2< target) l = mid +1;// 寻找第一个n使 (1+n) * n / 2 >= targetelse r = mid;}int sum =(1+ r)* r /2;return(sum - target)%2==0? r : r +1+ r %2;}}
1
2
3
4
5
6
7
8
9
10
11
12
13
或者可以使用二元一次方程公式计算出n
n
+
n
2
>
=
2
∗
t
a
r
g
e
t
n + n ^ 2 >= 2 * target
n+n2>=2∗target =>
n
>
=
(
s
q
r
t
(
8
∗
t
a
r
g
e
t
+
1
)
−
1
)
/
2
n >= (sqrt(8 * target + 1) - 1) / 2
n>=(sqrt(8∗target+1)−1)/2
时间复杂度:
O
(
1
)
O(1)
O(1)
空间复杂度:
O
(
1
)
O(1)
O(1)
classSolution{publicintreachNumber(int target){if(target <0) target =-target;int n =(int)Math.ceil((Math.sqrt(8L* target +1)-1)/2);int sum =(1+ n)* n /2;return(sum - target)%2==0? n : n +1+ n %2;}}