今天做了一道题目: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?
大致意思是:给定一个非负整型数字,重复相加其所有的数字直到最后的结果只有一位数。
看完题目觉得这道题很简单,不过看到后面的要求:不能使用任何循环和递归,而且在O(1)时间完成,这就觉得有点麻烦了。。。
不使用循环和递归能完成的话,说明给定的数字和结果一定存在某种规律,于是自己算了一下,
发现计算的之前的数和计算之后的数相差9的倍数。即
C0−C1=9S
。
其中
Cn
为C第n次计算后的数,S由
C0
的各个位数决定。
比如
C0=1234
。
则
C0=1∗103+2∗102+3∗101+4∗100
C1=1+2+3+4
C0−C1=1∗(103−1)+2∗(102−1)+3∗(101−1)+4∗(100−1)
=1∗999+2∗99+3∗9
=9∗(1∗111+2∗11+3∗1)
不过后面就没有头绪了。。。
于是在网上查了一下,发现了“Digital root(数根)”,维基百科里面介绍的很详细。
数根:将一非负整数的各个位数相加,若加完后的值大于等于10的话,则继续将各位数进行相加直到其值小于10为止,则所得的值为该数的数根。
求树根的方法是Congruence formula(同余式),公式如下:
不过自己还是想证明一下
刚刚得出
C0=C1+9S
,将两边模9,即:
C0(mod9)=(C1+9S)(mod9)
显然
C0≡C1(mod9)
所以一个数和它的各数位之和模9同余。
而数根d,是在0-10之间,即
0≤d≤9
所以数根
d(mod9)=d
因此
不过有一种特殊情况,当C是9的倍数时,数根为9。
知道了算法,接下来就是写代码了,代码很简单,就一句:
public class Solution {
public int addDigits(int num) {
return 1+(num-1)%9;
}
}
提交后,运行时间为2ms,但是!重点来了!!!
居然有0.04%的solution是1ms!!!
至今没找到1ms的方法。。。
希望在以后的学习中能够找到这个方法。
收获如下:
- 数根
- 一个数是不是9的倍数,可以通过该数各位数字之和来判断。
- 在MarkDown编辑器中插入公式
- 收获了几个英语单词:
congruence(同余)
formula(公式)
non-negative(非负)
recursion(递归)