1. Problem Description
Given a non-negative integer num, repeatedly add all its digits until the result has only one digit.For example:
Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it.
Follow up:
Could you do it without any loop/recursion in O(1) runtime?
给一个数字,一直求它的各位和,直到这个数字小于10为止。
2. My solution1(Loop)
直接模拟过程,其中wei是求各位和函数。class Solution {
public:
int wei(int num)
{
int ans=0;
while(num>0)
{
ans+=num%10;
num/=10;
}
return ans;
}
int addDigits(int num) {
int tmp=num;
while(tmp>=10)
tmp=wei(tmp);
return tmp;
}
};
3. My solution2(O[1]算法)
class Solution{
public:
int addDigits(int num)
{
if(num==0) return 0;
if(num%9==0) return 9;
else return num%9;
}
};
接下来我们将利用已知定理证明:
已知:
①( a + b ) % x =a % x + b % x
②递归重复求解一个x进制数num的各位之和,最终一定得到一个(0~x-1)之间的数
可得:
①一个n位x进制数num的各位之和对(x-1)取余,与这个数num本身对(x-1)取余的答案相同。
②递归重复求解一个x进制数num的各位之和对(x-1取余),与这个数num本身对(x-1)取余的答案相同。
证明:
任何一个10进制数num,都可以表示成这样一个多项式和,如4位数。
这里以2369为例。
8765=8+7+6+5+8*999+7*99+6*9+5*0
我们知道这个式子中右边的部分8*999+7*99+6*9+5*0一定可以被9整除,他们对9取余得到0。
又已知存在定理:
①( a + b ) % x =a % x + b % x
也就是说:
8765 % 9 =(8+7+6+5)% 9 +(8*999+7*99+6*9+5*0)% 9 =(8+7+6+5)% 9 ……………①
8765% 9 = 26 % 9 = 8
于是我们得到一个新的结论:
一个n位x进制数num的各位之和对(x-1)取余,与这个数num本身对(x-1)取余的答案相同。
现在我们想要知道这个数各位一直求和得到的0~9之间的数是多少,就将其对9取模即可。
所以得到return num%9就可以了。但是当num=9的倍数时,最后一步将得到9;当num=0时,又会得到0,需要特殊判定一下。
if(num==0) return 0;
if(num%9==0) return 9;
else return num%9;
网上总结出的公式,也可以直接:
return (num-1)%9+1