原题连接:258. Add Digits
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 <= 231 - 1
做法一:模拟
思路:
直接模拟,只要num不是一位数,就将它的各位相加
c++代码:
class Solution {
public:
int addDigits(int num) {
while(num >= 10){
int sum = 0;
// 各位相加的经典做法, 模10 除10
while(num > 0){
sum += num % 10;
num /= 10;
}
num = sum;
}
return num;
}
};
复杂度分析:
-
时间复杂度: O(lognum),对于num 计算一次各位相加需要 O(lognum) 的时间,而之后重复的相加的次数是O(1)级别的
-
空间复杂度: O(1)
做法二:数学性质
思路:
这道题的本质是计算自然数的数根。
数根又称数字根(Digital root),是自然数的一种性质,每个自然数都有一个数根。对于给定的自然数,反复将各个位上的数字相加,直到结果为一位数,则该一位数即为原自然数的数根。
利用自然数的性质,则能在O(1) 的时间内计算数根。
结论:
-
num 不是 9 的倍数时,其数根即为 num 除以 9 的余数。
-
num 是 9 的倍数时:
-
如果num=0,其数根是 0
-
如果num>0,其数根是 9。
-
c++代码:
class Solution {
public:
int addDigits(int num) {
int ans = 0;
if(num % 9) ans = num % 9;
else{
if(num == 0) ans = 0;
else ans = 9;
}
return ans;
}
};
复杂度分析:
- 时间复杂度: O(1)
- 空间复杂度: O(1)