数根与模算术
数根与模算术
数根的定义
在数学中,数根(又称位数根或数字根)是自然数的一种性质,换句话说,每个自然数都有一个数根。
数根是将一正整数的各个位数相加(即横向相加),若加完后的值大于10的话,则继续将各位数进行横向相加直到其值小于十为止[1],或是,将一数字重复做数字和,直到其值小于十为止,则所得的值为该数的数根。
例如54817的数根为7,因为5+4+8+1+7=25,25大于10则再加一次,2+5=7,7小于10,则7为54817的数根。
那么它的用途是什么?
-
数字根可作为一种检验计算正确性的方法。例如,两数字的和的数根等于两数字分别的数根的和。
例如 496866 + 446221 = 943087,“496866”,“446221”和“943087”他们的各个位上的数字相加起来分别是39、19和31,由于还是大于10,继续上面操作变成12、10和4,依次循环,最终获得3、1和4,发现什么?"两个相加的数的数字根等于结果的数字根!!!"
-
数根也可以用来判断数字的整除性,如果数根能被3或9整除,则原来的数也能被3或9整除。
其实小学就开始用了,我们最熟悉的就是判断某数是否可以被3整除!!!
那么为什么数根会产生这一性质呢?其背后的魔力是什么呢?——模算术
相信大伙对模都很熟悉,而模算术表示"用余数求和"。
关于模算术,有大量大学水平的数学,涉及环理论,等价类和所有其他方面,但你(可能)不关心这一点:你需要知道的是,如果你正常地对一个数取模(指定的模,可以是任何数)后得到的数和其它数取模后的答案进行加、减、乘后的结果,你会发现他们先加、减、乘后再取模,两者结果都是一样的。
举个例子
对4进行取模,那么57 + 94 = 151 = 3(模4)。57与1(模4)相同,94是2(模4),所以我们最终得到1(模4)+ 2(模4)= 3(模4)
试试另一个,模7。32 × 64 = 2048 = 4(模数 7)。32 是 4 (模 7), 64 是 1 (模 7)仍然成功!!!
让我们回到数根,讨论我们怎么求数根。
我们把 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
很多小伙伴对数根这类的方法都是用该数被10的方根所除后再进行相加,也正是这一原因使得计算量变大,而 我们总结出这一类问题可以用(n-1) mod 9 + 1
简化计算,也正是对9取模运算。
看到这边,可能还有些小伙伴不解了,按上面所述是对模9取模,再求和,那么假设有一个数为189,那么取模后不就是0吗?就与实际上1+8+9=18,1+8 = 9矛盾了吗?幸运的是9和0(模9)是相同的。
让我们取一个数,例如12345
12345
=
1
×
10000
+
2
×
1000
+
3
×
100
+
4
×
10
+
5
12345 =1×10000 + 2×1000 + 3×100 + 4×10 + 5
12345=1×10000+2×1000+3×100+4×10+5
现在,我们将10看做9 + 1;100是99 + 1,依次类推
12345
=
1
×
(
9999
+
1
)
+
2
×
(
999
+
1
)
+
3
×
(
99
+
1
)
+
4
×
(
9
+
1
)
+
5
12345 = 1×(9999 + 1) + 2×(999 + 1) + 3×(99 + 1) + 4×(9 + 1) + 5
12345=1×(9999+1)+2×(999+1)+3×(99+1)+4×(9+1)+5
重新整理下得:
12345
=
(
1
×
9999
+
2
×
999
+
3
×
99
+
4
×
9
)
+
(
1
+
2
+
3
+
4
+
5
)
12345 = (1×9999 + 2×999 + 3×99 + 4×9) + (1 + 2 + 3 + 4 + 5)
12345=(1×9999+2×999+3×99+4×9)+(1+2+3+4+5)
第一个括号我们不必关心,其中的元素都是9的倍数。第二个括号明显可以看出,是各个位数上数字的总和,即15或者说是6(模9)。如果你计算12345对9取模后得到的结果,你会发现其结果就是6!!!
这也就为什么我们是模9而不是模10。
我们可以看看一道力扣题各位相加
各位相加
此题若使用递归方法解决
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)
最佳方法利用数根
class Solution {
public:
int addDigits(int num) {
return (num - 1) % 9 + 1;
}
};
时间复杂度:O(1)
空间复杂度:O(1)
参考文章
如何证明一个数的数根(digital root)就是它对9的余数? - 知乎 (zhihu.com)
一个巧妙的数字技巧:数字根和模-9算术|飞行色彩数学 (flyingcoloursmaths.co.uk)