1. 问题定义

我们被给定一个数字 N,需要将其减少到 1,使用尽可能少的操作。允许的操作包括:

  1. 加1:当前数字变为 N + 1
  2. 减1:当前数字变为 N - 1
  3. 除以2(仅当数字为偶数时):当前数字变为 N / 2

例如:

  • N = 28,最优路径为:
    28 → 14 → 7 → 8 → 4 → 2 → 1(共6步)

  • N = 13,最优路径为:
    13 → 12 → 6 → 3 → 2 → 1(共5步)


2. 非最优贪心解法(Greedy)

思路

  • 如果 N 是偶数,就除以2
  • 如果 N 是奇数,就减1

示例

  • N = 10,路径为:
    10 → 5 → 4 → 2 → 1(共4步)

缺陷

该方法不总是最优。例如:

  • N = 15,贪心路径为:
    15 → 14 → 7 → 6 → 3 → 2 → 1(共6步)

但更优路径是:
15 → 16 → 8 → 4 → 2 → 1(共5步)

结论:速度快,但不保证最优解


3. BFS 解法(广度优先搜索)

思路

将每个数字视为图中的一个节点,节点之间通过加1、减1、除以2(偶数时)连接。

使用 BFS 搜索最短路径。

实现(伪代码)

algorithm BFSApproach(N):
    answer <- new array of size 2*N initialized to infinity
    queue <- new queue

    answer[N] <- 0
    queue.push(N)

    while not queue.empty():
        current <- queue.pop()

        if current == 1:
            break

        for next in [current+1, current-1, current/2 if even]:
            if answer[next] > answer[current] + 1:
                answer[next] = answer[current] + 1
                queue.push(next)

    return answer[1]

复杂度

  • 时间复杂度:O(N),其中 N 是起始数字
  • 空间复杂度:O(N)

优点:能保证最优解
缺点:效率不如贪心,尤其在大数时


4. 最优贪心解法(Optimal Greedy)

理论基础

  • 如果 N 是偶数 → 除以2
  • 如果 N 是奇数:
    • N == 3N % 4 == 1 → 减1
    • 否则 → 加1

示例

  • N = 15
    • 15 % 4 == 3 → 加1 → 16
    • 16 → 8 → 4 → 2 → 1(共5步)

实现(伪代码)

algorithm OptimalGreedyApproach(N):
    answer <- 0
    while N > 1:
        if N is even:
            N = N / 2
        else if N == 3 or N % 4 == 1:
            N = N - 1
        else:
            N = N + 1
        answer += 1
    return answer

复杂度

  • 时间复杂度:O(log N)
  • 空间复杂度:O(1)

优点:高效且最优
适用场景:大数场景下的最优解查找


5. 总结

我们讨论了三种方法来解决“将数字减少到1”的问题:

方法 是否最优 时间复杂度 适用场景
贪心法(非最优) O(log N) 快速近似解
BFS O(N) 小数字、需最优解
最优贪心法 O(log N) 大数字、需最优解

推荐:使用最优贪心法,兼顾效率和准确性
⚠️ 注意:在 N == 3 时要特殊处理(减两次)


原始标题:Minimum Number of Steps to Reduce Number to One