[数学] 258. 各位相加 (循环,递归 → 数学推导)

258. 各位相加

题目链接:https://leetcode-cn.com/problems/add-digits/


分类:

  • 数学:
    • 反复做各位相加直到一位数 = 求“数根”
    • 举例推导数学规律:数根 = num%9
    • 简单证明:x*100+y*10+z=x*99+y*9+x+y+z

在这里插入图片描述

思路1:使用循环

不断获取num的每一位,叠加后覆盖为新的num,继续获取num的每一位求和,直到num是个位数时,返回num即可。

如何获取num的每一位?

num % 10 可得到个位
num /= 10 可将num的int形式右移一位

例如十位移动到个位,再执行num%10可以得到当前的个位,也就是实际的十位。以此类推。

实现代码:

class Solution {
    public int addDigits(int num) {
        int res = 0;
        while(num / 10 > 0){//当num为个位数时退出循环
            //取num的每一位求和
            int backup = num;
            int sum = 0;
            while(backup > 0){
                sum += backup % 10;
                backup /= 10;
            }
            num = sum;//拿每一位叠加后的结果覆盖num
        }
        return num;
    }
}

思路2:使用递归

  • 递归函数功能:计算传递进来的参数的各位相加结果
  • 递归出口:如果num是个位数,则直接返回num本身。
  • 递归主体:计算num每一位之加sum,如果sum是个位数,则直接返回sum;如果sum不是个位数,则以sum为参数继续进入下一层递归。

实现代码:

class Solution {
    public int addDigits(int num) {
        //递归出口:num是个位数则直接返回num
        if(num / 10 == 0) return num;
        //计算num每一位之和
        int sum = addDigits(num / 10) + num % 10;
        //如果各位相加的结果是个位数则直接返回,不是个位数则继续对它进行按位求和
        if(sum / 10 > 0) return addDigits(sum);
        else return sum;
    }
}

思路3:数学规律(数根 = num%9)

参考题解 by windliang

一个非负数的每一位相加之和称作“数根”,举例:

原数: 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 

可以发现,每个数的数根以1-9循环,所以一个数num的数根 = num % 9.

但存在一个特殊情况:

  • 如果num是9的倍数,则它的数根是9,但num%9==0。

由此带来一个问题:代码如何编写能够同时兼容一般情况和特殊情况?

我们可以先将num-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 

可以发现所有数字都可以统一用这样的方式处理。当然分情况讨论来实现也是完全可以的。

num的数根=num%9 这一结论只是通过举例推导出来的,还没有得到证明,在 https://leetcode-cn.com/problems/add-digits/solution/java-o1jie-fa-de-ge-ren-li-jie-by-liveforexperienc/233789 评论区看到一个很简洁巧妙的证明:

num = x*100+y*10+z = x*99+y*9+x+y+z。
其中对x*99和y*9做mod 9 都等于0,所以num % 9 = x + y + z = 数根。

实现代码:

class Solution {
    public int addDigits(int num) {
        return (num - 1) % 9 + 1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值