力扣-258. 各位相加

1.题目

题目地址(258. 各位相加 - 力扣(LeetCode))

https://leetcode.cn/problems/add-digits/?envType=study-plan-v2&envId=primers-list

题目描述

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

 

示例 1:

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

示例 2:

输入: num = 0
输出: 0

 

提示:

  • 0 <= num <= 231 - 1

 

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

2. 题解

这道题的本质是计算自然数num的数根。
数根又称数字根(Digital root),是自然数的一种性质,每个自然数都有一个数根。对
于给定的目然数,反复将各个位上的数字相加,直到结果为一位数,则该一位数即为原自然数的数根。
计算数根的最直观的方法是模拟计算各位相加的过程,直到剩下的数字是一位数。利用自然数的性质,则能在\(O(1)\)的时间内计算数根。

2.1 模拟

思路

就是拆分,求和,再拆分,再求和; 直到只剩下个位数

代码

  • 语言支持:C++

C++ Code:


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;
    }
};

复杂度分析

令 n 为数组长度。

  • 时间复杂度:\(O(lognum)\)
  • 空间复杂度:\(O(1)\)

2.2 数学方法(拆分-补缺)

思路

假设整数num的十进制表示有\(n\)位,从最低位到最高位依次是\(a_0\)\(a_{n-1}\)
则 num 可以写成如下形式(每一位都分出来个1, 用于构成树根):

\(\begin{aligned} num& =\sum_{i=0}^{n-1}a_i\times10^i \\ &=\sum_{i=0}^{n-1}a_i\times(10^i-1+1) \\ &=\sum_{i=0}^{n-1}a_i\times(10^i-1)+\sum_{i=0}^{n-1}a_i \end{aligned}\)

\(i=0\)时,\(10^i-1=0\)是 9 的倍数;
\(i\)是正整数时,\(10^i-1\)是由\(i\)位9 组成的整数,也是 9 的倍数。
因此对于任意非负整数\(i,10^i-1\)都是 9 的倍数。由此可得num与其各位相加的结果模 9 同余。
重复计算各位相加的结果果直到结果为一位数时,该一位数即为num的数根,num与其数根模 9 同余。

我们对num分类讨论:
num不是 9 的倍数时,其数根即为num除以 9 的余数。
num是 9 的倍数时:
\(\circ\)如果\(num=0\),则其数根是0;
\(\circ\)如果\(num>0\) ,则各位相加的结果大于0,其数根也大于0,因此其数根是 9。

细节

根据上述分析可知,当\(num>0\)时,其数根的结果在范围[1,9] 内,因此可以想到计算\(num-1\)除以 9 的余数然后加 1。
由于当\(num>0\)时,\(num-1\geq0\) ,非负数除以 9 的余数一定也是非负数,因此计算\(num-1\)除以 9 的余数然后加 1 的结果是正确的。

\(num=0\)时,\(num-1=-1<0\) ,负数对 9 取余或取模的结果的正负在不同语言中有所不同。
\(\circ\)对于取余的语言,结果的正负和左操作数相同,则\(num-1\)对 9 取余的结果为-1 ,加 1 后得到结果0,可以得到正确的结果;
\(\circ\)对于取模的语言,结果的正负和右操作数相同,则\(num-1\)对 9 取模的结果的果为 8,加 1 后得到结果 9,无法得到正确的结果,此时需要对\(num=0\)的情况专门做处理。

代码

class Solution {
public:
    int addDigits(int num) {
        return (num - 1) % 9 + 1;
    }
};
posted @ 2024-04-29 15:10  DawnTraveler  阅读(18)  评论(0编辑  收藏  举报