给定一个非负整数 num
,反复将各个位上的数字相加,直到结果为一位数。
示例:
输入:38
输出: 2 解释: 各位相加的过程为:3 + 8 = 11
,1 + 1 = 2
。 由于2
是一位数,所以返回 2。
进阶:
你可以不使用循环或者递归,且在 O(1) 时间复杂度内解决这个问题吗?
解题思路:
硬解:循环相加各位数
class Solution {
public:
int addDigits(int num) {
int sum=0;
while(num!=0){
sum+=num%10;
num/=10;
}
while(sum>=10){
int s=0;
while(sum!=0){
s+=sum%10;
sum/=10;
}
sum=s;
}
return sum;
}
};
令解:数字根
非负整数的数字根(也是重复的数字和)是通过对每个迭代进行求和的迭代过程而获得的(单个数字)值,使用来自先前迭代的结果来计算数字和。该过程一直持续到达到一位数的数字。
同余公式
公式是:
要么,
为了将数字根的概念概括为其他基数b,可以简单地将公式中的9改为b -1。
数字根是模9的值,因为 因此 所以无论位置如何,mod 9的值都是相同的 - 这就是可以有意义地添加数字的原因。具体地说,对于三位数字,
等于a + b + c 。
为了获得相对于其他数字n的模数值,可以采用加权和,其中第k个数字的权重对应于模数,或类似的对于不同的基础。对于2,5和10来说这是最简单的,其中较高的数字消失(因为2和5除以10),这对应于熟悉的事实,即可以通过以下方法检查相对于2,5和10的十进制数的可除性。最后一位数(偶数以0,2,4,6或8结尾)。
另外值得注意的是模数11:因为 因此 取交替的数字和产生模11的值。
class Solution {
public:
int addDigits(int num) {
return 1 + (num - 1) % 9;
}
};