目录

LC 258. 各位相加 (opens new window) (opens new window)

简单

# 问题描述

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

示例 1:

输入: num = 38
输出: 2
解释: 各位相加的过程为:
38 --> 3 + 8 --> 11
11 --> 1 + 1 --> 2
由于  2 是一位数,所以返回 2。

示例 2:

输入: num = 0
输出: 0

提示:

  • 0 <= num <= 231 - 1

进阶:你可以不使用循环或者递归,在 O(1) 时间复杂度内解决这个问题吗?

# 模拟

按题意模拟。

/**
 * @param {number} num
 * @return {number}
 */
var addDigits = function (num) {
  let ans = num
    .toString()
    .split('')
    .reduce((sum, n) => sum + +n, 0)
  while (ans > 9) {
    ans = addDigits(ans)
  }
  return ans
}
  • 时间复杂度:O(lognum)O(log\;num)
  • 空间复杂度:O(1)O(1)

# 数学

数学上,这道题是求给出的数的数根 (opens new window)

对于某个 nn 位的十进制整数 numnum,假设从最低位到最高位依次是 a0,a1,,an1a_0, a_1, \dots, a_{n-1},那么这个数可以表示为:

num=i=0n1ai×10inum = \sum_{i=0}^{n-1} a_i \times 10^i

显然 10imod9=110^i\;\text{mod}\;9 = 1,因此可得:

nummod9=i=0n1aimod9num\;\text{mod}\;9 = \sum_{i=0}^{n-1} a_i\;\text{mod}\;9

f(x)=i=0n1aimod9f(x) = \sum_{i=0}^{n-1} a_i\;\text{mod}\;9,那么 f(x)=xmod9f(x) = x\;\text{mod}\;9,那么 f(f(x))=(xmod9)mod9xmod9f(f(x)) = (x\;\text{mod}\;9)\;\text{mod}\;9 \equiv x\;\text{mod}\;9,但是数根的取值范围是 [1,9][1,9],对 99 取余的取值范围为 [0,8][0,8],可以先将给定的数字减 11,相当于原数整体向左偏移了 11,然后再将得到的数字对 99 取余,最后将得到的结果加 11

/**
 * @param {number} num
 * @return {number}
 */
var addDigits = function (num) {
  return ((num - 1) % 9) + 1
}
  • 时间复杂度:O(1)O(1)
  • 空间复杂度:O(1)O(1)
上次更新: 2023/01/31 19:48:05

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 , 转载请注明出处!