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;
    }
};

令解:数字根

非负整数数字根(也是重复的数字和)是通过对每个迭代进行求和的迭代过程而获得的(单个数字)值,使用来自先前迭代的结果来计算数字和。该过程一直持续到达到一位数的数字。

同余公式

公式是:

{\ displaystyle \ operatorname {dr}(n)= {\ begin {cases} 0&{\ mbox {if}} \ n = 0,\\ 9&{\ mbox {if}} \ n \ neq 0,\ n \ \ equiv 0 {\ pmod {9}},\\ n \ {​{rm {mod}} \ 9&{\ mbox {if}} \ n \ not \ equiv 0 {\ pmod {9}} \ end {cases} }}

要么,

{\ displaystyle {\ mbox {dr}}(n)= 1 \ + \((n-1)\ {\ rm {mod}} \ 9)。}

为了将数字根的概念概括为其他基数b,可以简单地将公式中的9改为b -1。

(序列A010888OEIS

数字根是模9的值,因为 10 \ equiv 1 {\ pmod {9}}, 因此 10 ^ {k} \ equiv 1 ^ {k} \ equiv 1 {\ pmod {9}}, 所以无论位置如何,mod 9的值都是相同的 a \ cdot 100 \ equiv a \ cdot 10 \ equiv a {\ pmod {9}} - 这就是可以有意义地添加数字的原因。具体地说,对于三位数字,

等于a + b + c {\ mbox {dr}}(abc)\ equiv a \ cdot 10 ^ {2} + b \ cdot 10 + c \ cdot 1 \ equiv a \ cdot 1 + b \ cdot 1 + c \ cdot 1 \ equiv a + b + c {\ pmod {9}}

为了获得相对于其他数字n的模数值可以采用加权和,其中第k个数字的权重对应于10 ^ {K}数,或类似的b ^ {K}对于不同的基础。对于2,5和10来说这是最简单的,其中较高的数字消失(因为2和5除以10),这对应于熟悉的事实,即可以通过以下方法检查相对于2,5和10的十进制数的可除性。最后一位数(偶数以0,2,4,6或8结尾)。

另外值得注意的是模数11:因为 10 \ equiv -1 {\ pmod {11}}, 因此 10 ^ {2} \ equiv(-1)^ {2} \ equiv 1 {\ pmod {11}},交替的数字和产生模11的值。

class Solution {
public:
    int addDigits(int num) {
        return 1 + (num - 1) % 9;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值