【2022-11-04每日一题】754. 到达终点数字[Medium]
2022-11-04
2分钟阅读时长
2022-11-04每日一题:754. 到达终点数字
难度:Medium
标签:数学 、 二分查找
在一根无限长的数轴上,你站在0
的位置。终点在target
的位置。
你可以做一些数量的移动 numMoves
:
- 每次你可以选择向左或向右移动。
- 第
i
次移动(从i == 1
开始,到i == numMoves
),在选择的方向上走i
步。
给定整数 target
,返回 到达目标所需的 最小 移动次数(即最小 numMoves
) 。
示例 1:
输入: target = 2 输出: 3 解释: 第一次移动,从 0 到 1 。 第二次移动,从 1 到 -1 。 第三次移动,从 -1 到 2 。
示例 2:
输入: target = 3 输出: 2 解释: 第一次移动,从 0 到 1 。 第二次移动,从 1 到 3 。
提示:
-109 <= target <= 109
target != 0
方法一:官方分析+数学
详细思路过程见官方题解,这里只做个人刷题记录,方便后续查询阅读
func reachNumber(target int) int {
// 如果是负数,转为正数
if target < 0 {
target = -target
}
k := 0
for target > 0 {
k++
target -= k
}
// 此时 target 小于等于 0
// 如果target此时为偶数,一定可以再k前面找到和为 target/2 的数
if target%2 == 0 {
return k
}
return k+1+k%2
}
复杂度分析
时间复杂度:O(target)。循环内最多执行 O(target) 次。
空间复杂度:O(1)。只使用常数空间。
灵茶山艾府
分类讨论
func reachNumber(target int) int {
if target < 0 {
target = -target
}
s, n := 0, 0
// 没有到达(越过)终点,或者相距奇数
// (s-target)%2 == 1 等价于 (s-target)%2 != 0
for s < target || (s-target)%2 == 1 {
n++
s += n
}
return n
}
复杂度分析
- 时间复杂度:O(∣target∣)。
- 空间复杂度:O(1),仅用到若干变量。
优化
func reachNumber(target int) int {
if target < 0 {
target = -target
}
n := int(math.Ceil((-1 + math.Sqrt(float64(8*target+1))) / 2))
if (n*(n+1)/2-target)%2 == 0 {
return n
}
return n + 1 + n%2
}
复杂度分析
- 时间复杂度:O(1)。
- 空间复杂度:O(1),仅用到若干变量。