6.9.2022 lintcode每日打卡 569 各位相加

这篇博客探讨了一个数学问题,即如何通过不断将整数的各位数字相加,直到得到一个一位数的过程,称为求整数的数根。文章给出了一个O(1)时间复杂度的解决方案,利用数论中的性质,通过计算num-1除以9的余数并加1得到结果。当num不为9的倍数时,数根即为num除以9的余数;若num是9的倍数,需要根据num是否为0来确定数根。最后,提供了一个Python实现的函数,用于计算整数的数根。
摘要由CSDN通过智能技术生成

描述

给出一个非负整数 num,反复的将所有位上的数字相加,直到得到一个一位的整数。

样例

例1:

 
输入:
num=38
输出:
2
解释:
过程如下: 3 + 8 = 11, 1 + 1 = 2. 因为 2 只有一个数字,返回 2.

例2:

 
输入:
num=9
输出:
9
解释:
9<10,返回 9.

挑战

你可以不用任何的循环或者递归算法,在 O(1) 的时间内解决这个问题么?

思路:

这个是官方思路很棒的想法每个大于0的数 他们的倍数都会在【1-9】之间,然后我们取最大的,如果是9的倍数就是0,超过9就进一位,然后我们要把0也算进去所以num>0 得-1让一位 变成num-1>=0,然后得到的mod要+1因为要进一位。以上是我的理解 我贴一下他怎么讲的:

思路和算法

假设整数 \textit{num}num 的十进制表示有 nn 位,从最低位到最高位依次是 a_0a0​ 到 a_{n - 1}an−1​,则 \textit{num}num 可以写成如下形式:

\begin{aligned} \textit{num} &= \sum_{i = 0}^{n - 1} a_i \times 10^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}num​=i=0∑n−1​ai​×10i=i=0∑n−1​ai​×(10i−1+1)=i=0∑n−1​ai​×(10i−1)+i=0∑n−1​ai​​

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

我们对 \textit{num}num 分类讨论:

  • \textit{num}num 不是 99 的倍数时,其数根即为 \textit{num}num 除以 99 的余数。

  • \textit{num}num 是 99 的倍数时:

    • 如果 \textit{num} = 0num=0,则其数根是 00;

    • 如果 \textit{num} > 0num>0,则各位相加的结果大于 00,其数根也大于 00,因此其数根是 99。

细节

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

当 \textit{num} = 0num=0 时,\textit{num} - 1 = -1 < 0num−1=−1<0,负数对 99 取余或取模的结果的正负在不同语言中有所不同。

  • 对于取余的语言,结果的正负和左操作数相同,则 \textit{num} - 1num−1 对 99 取余的结果为 -1−1,加 11 后得到结果 00,可以得到正确的结果;

  • 对于取模的语言,结果的正负和右操作数相同,则 \textit{num} - 1num−1 对 99 取模的结果为 88,加 11 后得到结果 99,无法得到正确的结果,此时需要对 \textit{num} = 0num=0 的情况专门做处理。

class Solution:
    """
    @param num: a non-negative integer
    @return: one digit
    """
    def add_digits(self, num: int) -> int:
        # write your code here
        return (num-1)%9+1 if num else 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值