258. 各位相加

给定一个非负整数 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。

(序列A010888在OEIS)

数字根是模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;
    }
};

 

你可能感兴趣的:(LeetCode)