258.各位相加

11 阅读1分钟

给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。返回这个结果。

方法一:模拟循环相加(直观解法)

思路:不断将数字的各位相加,直到结果为一位数。

代码实现

def addDigits(num: int) -> int:
    while num >= 10:
        total = 0
        while num > 0:
            total += num % 10
            num = num // 10
        num = total
    return num

复杂度分析

  • 时间复杂度O(logn)O(log n),每次操作将数字位数减少约一个数量级。
  • 空间复杂度O(1)O(1)

方法二:数学公式(数根公式)

思路:利用数根的数学性质,对于非零数 n,其数根为 (n-1) % 9 + 1;对于零,结果为 0。

推导过程

  • 数根满足公式:dr(n) = n - 9 * floor((n-1)/9),简化后为 (n-1) % 9 + 1
  • 例如:
    • n = 38(38-1) % 9 + 1 = 37 % 9 + 1 = 1 + 1 = 2
    • n = 0,直接返回 0。

代码实现

def addDigits(num: int) -> int:
    if num == 0:
        return 0
    return (num - 1) % 9 + 1

复杂度分析

  • 时间复杂度O(1)O(1),仅需一次数学运算。
  • 空间复杂度O(1)O(1)

测试示例

  • 输入 num = 38,输出 2
  • 输入 num = 0,输出 0
  • 输入 num = 9999,输出 9(因为 9999 → 36 → 9)。