一【题目类别】
- 数学
二【题目难度】
- 简单
三【题目编号】
- 258.各位相加
四【题目描述】
- 给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。返回这个结果。
五【题目示例】
-
示例 1:
- 输入: num = 38
- 输出: 2
- 解释: 各位相加的过程为:
- 38 --> 3 + 8 --> 11
- 11 --> 1 + 1 --> 2
- 由于 2 是一位数,所以返回 2。
- 解释: 各位相加的过程为:
-
示例 2:
- 输入: num = 0
- 输出: 0
六【解题思路】
- 方法一:
- 正常模拟即可,当num还大于等于10的时候就需要将各位循环相加
- 每次循环内只需要将每一位取出来相加
- 然后赋值给num,准备做下一轮各位相加
- 直到num小于10,变为1位数时结束循环
- 最后返回结果即可
- 此方法的时间复杂度为 O ( l o g n ) O(logn) O(logn),其中 n n n为传入参数的大小
- 方法二:
- 在这里简单介绍一下数根的概念:数根是将一正整数的各个位数相加(即横向相加),若加完后的值大于10的话,则继续将各位数进行横向相加直到其值小于十为止,或是,将一数字重复做数字和,直到其值小于十为止,则所得的值为该数的数根。本题就是要求一个数的数根
- 当然,严谨的证明在这里并不做演示,此思想最重要的一点就是:num对9取模与其数根相等(特殊情况会在下面说明)
- 我们需要知道其性质:
- 0的数根是0
- 当num是9的倍数时:数根就是9
- 当num不是9的倍数时:数根就是num对9取模
- 按照上方的过程就可以完成本题
- 最后返回结果即可
- 此方法的时间复杂度为 O ( 1 ) O(1) O(1)
七【题目提示】
- 0 < = n u m < = 2 31 − 1 0 <= num <= 2^{31} - 1 0<=num<=231−1
八【题目进阶】
- 你可以不使用循环或者递归,在 O ( 1 ) O(1) O(1) 时间复杂度内解决这个问题吗?
九【时间频度】
- 时间复杂度:
- 方法一: O ( l o g n ) O(logn) O(logn),其中 n n n为传入参数的大小
- 方法二: O ( 1 ) O(1) O(1)
- 空间复杂度:
- 方法一: O ( 1 ) O(1) O(1)
- 方法二: O ( 1 ) O(1) O(1)
十【代码实现】
- Java语言版
class Solution {
public int addDigits(int num) {
while(num >= 10){
int sum = 0;
while(num > 0){
sum += num % 10;
num /= 10;
}
num = sum;
}
return num;
}
}
- C语言版
int addDigits(int num)
{
if(num == 0)
{
return 0;
}
else if(num % 9 == 0)
{
return 9;
}
else
{
return num % 9;
}
}
- Python版
class Solution:
def checkPerfectNumber(self, num: int) -> bool:
if num == 1:
return False
res = 1
i = 2
while i * i <= num:
if num % i == 0:
res += i
if i * i < num:
res += num / i
i += 1
return res == num
十一【提交结果】
-
Java语言版
-
C语言版
-
Python语言版