【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),仅用到若干变量。

LeetCode题库地址