title | description | keywords | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
258. 各位相加 |
LeetCode 258. 各位相加题解,Add Digits,包含解题思路、复杂度分析以及完整的 JavaScript 代码实现。 |
|
🟢 Easy 🔖 数学
数论
模拟
🔗 力扣
LeetCode
Given an integer num
, repeatedly add all its digits until the result has
only one digit, and return it.
Example 1:
Input: num = 38
Output: 2
Explanation: The process is
38 --> 3 + 8 --> 11
11 --> 1 + 1 --> 2
Since 2 has only one digit, return it.
Example 2:
Input: num = 0
Output: 0
Constraints:
0 <= num <= 2^31 - 1
Follow up: Could you do it without any loop/recursion in O(1)
runtime?
给定一个非负整数 num
,反复将各个位上的数字相加,直到结果为一位数。返回这个结果。
示例 1:
输入: num = 38
输出: 2
解释: 各位相加的过程为:38 --> 3 + 8 --> 11
11 --> 1 + 1 --> 2
由于 2 是一位数,所以返回 2。
示例 2:
输入: num = 0
输出: 0
提示:
0 <= num <= 2^31 - 1
进阶: 你可以不使用循环或者递归,在 O(1)
时间复杂度内解决这个问题吗?
- 每次将数字的各位相加。
- 如果结果仍然大于 9,继续重复此过程。
- 当数字小于 10 时,返回结果。
- 时间复杂度:
O(log_10 n)
,每次循环会减少一位数字。 - 空间复杂度:
O(1)
,只需要常量额外空间。
- 数字根的概念(Digital Root)可用于快速找到结果:
- 如果
num == 0
,结果为0
。 - 如果
num != 0
,结果为1 + (num - 1) % 9
。 - 公式来源:将数字
num
按照 10 进制分解后,可以得出其各位数字和对 9 取模的规律。
- 如果
- 使用公式直接计算,无需循环或递归。
- 时间复杂度:
O(1)
,仅进行常数次数学运算。 - 空间复杂度:
O(1)
,不需要额外空间。
- 如果
num
小于 10,直接返回。 - 否则,将
num
的各位相加后递归调用自身。
- 时间复杂度:
O(log_10 n)
,每次递归会减少一位数字。 - 空间复杂度:
O(log_10 n)
,递归调用栈的深度。
方法 | 时间复杂度 | 空间复杂度 | 备注 |
---|---|---|---|
模拟逐步相加 | O(log_10 n) |
O(1) |
简单直观,代码可读性强 |
数学方法 | O(1) |
O(1) |
最优解,高效且无需循环 |
递归法 | O(log_10 n) |
O(log_10 n) |
简单实现,但递归耗费栈空间 |
::: code-tabs @tab 模拟逐步计算
var addDigits = function (num) {
while (num >= 10) {
let sum = 0;
while (num > 0) {
sum += num % 10; // 提取个位数并累加
num = Math.floor(num / 10); // 去掉个位
}
num = sum;
}
return num;
};
@tab 数学方法
var addDigits = function (num) {
if (num === 0) return 0;
return 1 + ((num - 1) % 9);
};
@tab 递归法
var addDigits = function (num) {
if (num < 10) return num;
let sum = 0;
while (num > 0) {
sum += num % 10;
num = Math.floor(num / 10);
}
return addDigits(sum);
};
题号 | 标题 | 题解 | 标签 | 难度 | 力扣 |
---|---|---|---|---|---|
202 | 快乐数 | [✓] | 哈希表 数学 双指针 |
🟢 | 🀄️ 🔗 |
1085 | 最小元素各数位之和 🔒 | 数组 数学 |
🟢 | 🀄️ 🔗 | |
1945 | 字符串转化后的各位数字之和 | [✓] | 字符串 模拟 |
🟢 | 🀄️ 🔗 |
2160 | 拆分数位后四位数字的最小和 | [✓] | 贪心 数学 排序 |
🟢 | 🀄️ 🔗 |
2243 | 计算字符串的数字和 | [✓] | 字符串 模拟 |
🟢 | 🀄️ 🔗 |
2535 | 数组元素和与数字和的绝对差 | 数组 数学 |
🟢 | 🀄️ 🔗 | |
2544 | 交替数字和 | 数学 |
🟢 | 🀄️ 🔗 |