LeetCode - 258. 各位相加

一. 题目描述

给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。

示例:

输入: 38
输出: 2 
解释: 各位相加的过程为3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。

进阶:
你可以不使用循环或者递归,且在 O(1) 时间复杂度内解决这个问题吗?

二. 代码

      emmm, 拿到这道题, 瞬间就想到了循环的解法,感叹,这是一道多么简单的题目,然后, 直接翻到进阶的要求, 直接傻眼了,这要怎么才能实践O(1)?这里面难道还有什么深藏的数学不成。

      然后, 翻了一些博客, 发现,真的藏着其数学特性。这里先贴一下代码。(最后附有代码出处)

/**
 * 功能说明:LeetCode 258 - Add Digits
 * 开发人员:Tsybius2014
 * 开发时间:2015年8月25日
 */
public class Solution {
    
    /**
     * 给定整数不断将它的各位相加,直到相加的结果小于10,返回结果
     * @param num
     * @return
     */
    public int addDigits(int num) {
        return (num - 1) % 9 + 1;
    }
}

三. 解析

1. 这个解法,乍一看,我是懵的,凭什么对9求余,就可以直接得到结果了。所以,我就好好学习了一把。

2. 为了方便后续翻看我参考的文章(其实也可以说是转载了), 我也一样假设输入的数字是一个5位数字num,那么num的各位分别为a、b、c、d、e。

有如下关系:num = a * 10000 + b * 1000 + c * 100 + d * 10 + e

即:num = (a + b + c + d + e) + (a * 9999 + b * 999 + c * 99 + d * 9)

其中,a * 9999 + b * 999 + c * 99 + d * 9 一定可以被9整除,也就是说 num % 9 == ( a + b + c + d + e ) % 9。

3. 我们可以继续假设 num2 = ( a + b + c + d + e ),那么这个num2的位数最大不超过两位,不失一般性,这里假设num2为2位数。

则根据第二步的推论,可得出: num2 = k1 * 10 + k2

即: num2 = (k1 + k2) + ( k1 * 9 )

最终得出:num2 % 9 == (k1 + k2) % 9, 那么到这里就比较明朗了,由于 (k1 + k2) < num2  ( k1 > 0 的情况下), 只要不断迭代下去最终k1 + k2 < 10 的情况必定会出现,而我们需要保留的就是最终这个k1 + k2 的值。

4. 由以上的推到可以得出,num % 9 == (k1 + k2) % 9,且k1 + k2 < 10 的情况就是我们需要的结果。而当k1 + k2 < 9时, k1 + k2 % 9 == k1 + k2,但是这个式子并不能适应于k1 + k2 == 9的情况,所以修改了一下,就变成了( k1 + k2 - 1 ) % 9  + 1 的形式。转换一下,就是(num - 1) % 9 + 1 == ( k1 + k2 - 1) % 9 + 1。

四. 参考

https://my.oschina.net/Tsybius2014/blog/497645

猜你喜欢

转载自blog.csdn.net/qq_28634403/article/details/82967171
今日推荐