简介

数根又称数字根(Digital root),是自然数的一种性质,每个自然数都有一个数根。对于给定的自然数,反复将各个位上的数字相加,直到结果为一位数,则该一位数即为原自然数的数根。显然,数根的范围在[1,9]之间。

如何计算数根

最直观的方法是模拟各位相加的过程,直到剩下的数字是一位数。

计算一个整数的各位相加的做法是,每次计算当前整数除以 10 的余数得到最低位数,将最低位数加到总和中,然后将当前整数除以 10。重复上述操作直到当前整数变成 000,此时的总和即为原整数各位相加的结果。
LeetCode官方给出的题解:

class Solution {
    public int addDigits(int num) {
        while (num >= 10) {
            int sum = 0;
            while (num > 0) {
                sum += num % 10;
                num /= 10;
            }
            num = sum;
        }
        return num;
    }
}

该算法的时间复杂度为O(logn)
下面介绍一种可以在 O(1) 的时间内完成求解的算法:
对于任意一个整数 \(num\) , 我们有 \(num = \sum_{i=0}^{n-1}a_i * 10^i\), 稍做变换,有$nu m=\sum_{i=0}^{n-1}a_i *(10^i-1+1) =\sum_{i=0}^{n-1}a_i *(10^i-1) + \sum_{i=0}^{n-1}a_i $.

由于 \(10^i-1\) 一定被9整除,因此 \(num\) 与其各位数字之和模9同余,重复计算各位相加之和,由于同余的传递性,知 \(num\) 的数根与 \(num\) 模9同余。因此:
1. 若 \(num\) 不是9的倍数,则数根为 \(num\) mod \(9\) .
2.若 \(num\) 是9的倍数,则数根为9,这是因为 \(num\) 与数根模9同余,而数根介于[1,9]之间.
3.若 \(num=0\), 则数根为0.
代码如下:

int addDigits(int num)
{
    return (num - 1) % 9 + 1;
}

例题:
各位相加

数根的性质

下面简单介绍一下数根的性质:
( 1 ) 9加上任何正整数所得的和的数字根,等于原来数字的数字根
( 2 )9乘以任何正整数所得的积的数字根为9。可以看成任意正整数个9相加
( 3 )两个正整数相加,原来两个数的数字根之和等于和的数字根
( 4 )两个正整数相乘,原来两个数的数字根之积等于积的数字根

posted on 2023-05-02 23:00  sc01  阅读(466)  评论(0编辑  收藏  举报