首先该题如果用递归或者是迭代的方法来做很简单,我们下面主要想说的是该题隐藏的一个数学知识点——数根(题目所求即数根)
数根可以计算模运算的同余,对于非常大的数字的情况下可以节省很多时间。
数字根可作为一种检验计算正确性的方法。例如,两数字的和的数根等于两数字分别的数根的和。
另外,数根也可以用来判断数字的整除性,如果数根能被3或9整除,则原来的数也能被3或9整除
接下来讨论我们怎么求出树根。
我们把 1 到 30 的树根列出来。
原数: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
数根: 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3
可以发现数根 9 个为一组, 1 - 9 循环出现。我们需要做就是把原数映射到树根就可以,循环出现的话,想到的就是取余了。
结合上边的规律,对于给定的 n 有三种情况。
n 是 0 ,数根就是 0。
n 不是 9 的倍数,数根就是 n 对 9 取余,即 n mod 9。
n 是 9 的倍数,数根就是 9。
我们可以把两种情况统一起来,我们将给定的数字减 1,相当于原数整体向左偏移了 1,然后再将得到的数字对 9 取余,最后将得到的结果加 1 即可。
原数是 n,树根就可以表示成 (n-1) mod 9 + 1,可以结合下边的过程理解。
原数: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
偏移: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
取余: 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8 0 1 2
数根: 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3
class Solution {
public://这样也可
int addDigits(int num) {
if(!num)
return 0;
if(num%9==0)
return 9;
else
return num%9;
}
};
下面也给出迭代和递归的写法
class Solution {
public://循环
int addDigits(int num) {
int sum=0,onum=num;
while((num/10)!=0)
{
sum=0;
onum=num;
while(onum)
{
sum+=onum%10;
onum/=10;
}
num=sum;
}
return num;
}
};
class Solution {
public://递归
int addDigits(int num) {
if(num<10)
return num;
else
return addDigits(num%10+num/10);
}
};