题目:Add Digits
原题链接
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?
给出一个自然数,重复累加各个位上的和直到和只有一位的时候,要求尽量不用循环或者递归并且常数级时间复杂度。
题意的定义是一个数字根的概念:
(摘自百度百科)数根(又称数字根Digital root)是自然数的一种性质,换句话说,每个自然数都有一个数根。
数根是将一正整数(博主注:0也可以)的各个位数相加(即横向相加),若加完后的值大于等于10的话,则继续将各位数进行横向相加直到其值小于十为止,或是,将一数字重复做数字和,直到其值小于十为止,则所得的值为该数的数根。例如54817的数根为7,因为5+4+8+1+7=25,25大于10则再加一次,2+5=7,7小于十,则7为54817的数根。
关于数字根有一个公式可以直接得出结果,下面来简单的推导一下,推导的重心就是两点:
- 0到9的数字根是其本身;
- 任何正整数加上9数字根不变;
第一点显而易见,第二点大致可以分3中情况,第一种,个位不进位,即个位是0,加上9之后各位就是9,此时可以可以实验一下各位和十位的数字相加仍然不变;第二种,各位进位,十位不进位,这种情况下个位加9的结果会造成个位数字减一,由于进位,十位数字会加一,两者相加和依然不变;第3种,十位也进位,这种情况下本质上依旧是各位减一,然后高位如果本来是9的就会变成0,根据前面的结论,9变成0并不会影响最终的和,然后如果高位不是9的最终会加1,这样和个位的减一再次抵消,和不变。综上,这个结论是正确的。
这样看起来好像直接把n对9取余就有结果了,但是还有点小问题,那就是9的倍数这类情况,结果应该是9,但是取余反而会变成0。解决方法是稍微转化一下: 1+(n - 1) % 9,这样的话就可以避免上述情况了。
本题代码如下:
class Solution {
public:
int addDigits(int num) {
return 1 + (n - 1) % 9;
}
};