这道题是LeetCode里的第258道题。
题目描述:
给定一个非负整数
num
,反复将各个位上的数字相加,直到结果为一位数。示例:
输入: 38 输出: 2 解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。由于 2 是一位数,所以返回 2。进阶:
你可以不使用循环或者递归,且在 O(1) 时间复杂度内解决这个问题吗?
如果我们用循环做的话,首先先确定终止条件:最后的和小于 10,然后在循环内部再进行运算。
还有一种数学推理思路:
我们首先我们假设一个数为 abcd。其可以写成 1000*a+100*b+10*c+d,这时我们把各个位数相加等于 a+b+c+d=sum,再计算它们之间的差值:(1000*a+100*b+10*c+d)-(a+b+c+d) = 999*a+99*b+9c。差值是一个 9 的倍数。而且此时 sum 一定是一个十位数,我们观察一下十位数的各位相加的结果:
- 1 -> 1
- 13 -> 4
- 45 -> 9
- 78 -> 15 -> 6
- 89 -> 17 -> 8
然后再对它们对9求余观察一下结果:
- 1%9 -> 1
- 13%9 -> 4
- 45%9 -> 0
- 78%9 -> 6
- 89%9 -> 8
结果除了9的倍数外,是不是都相等的!
为什么是这个结果呢?那我们再对这些十位数分析:把十位数写成 10*x+y,各位相加的和 x+y,差值:9*x,这也是一个 9 的倍数!
也就是说我们要求的 abcd 四位数的各位相加和,其实就是减去一个 9 的倍数的差值,那么我们就可以对所求数 abcd 对 9 求余,就能得到答案。即 abcd%9 = 所求解。但是有一个特殊的情况,当 abcd 刚好是 9 的倍数时,我们求的解不是 0,而是 9。
以上的数学分析可以拓展到所有的整数。
解题代码:
class Solution {
public int addDigits(int num) {
return num%9==0?(num==0?0:9):num%9;
}
}
提交结果:
个人总结:
这种题多做做挺好的,发现数字的乐趣所在。