LeetCode 258: Add Digits 题解

刚开始以为是一道水题,一下就过了,结果题没看完,要求时间复杂度为 O(1)


LeetCode 258: Add Digits
Given a non-negative integer num, repeatedly add all its digits until the result has only one digit.

For example:

Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it.

Follow up:
Could you do it without any loop/recursion in O(1) runtime?


用循环或者递归的话在思想上很简单,下面是水过的代码:

int addDigits(int num) {
    while(num >= 10){
        int temp_sum = 0;
        while(num > 0){
            temp_sum += num % 10;
            num /= 10;
        }
        num = temp_sum;
    }
    return num;
}

下面来看看怎么不用循环或者递归来解这道题。

解法1:

这道题其实是有规律的:

n结果
101
112
123
134
145
156
167
178
189
191
202
213


答案就是对9取余,但是9的倍数取余为0,所以要处理特殊情况:

int addDigits(int num) {
    return (num != 0 && 0 == num % 9) ? 9 : num % 9;
}

解法2:

下面的例子引用自该题的discussion

首先需要知道:
10^k % 9 = 1
a*10^k % 9 = a % 9

假如有一个数字 x = 23456

x = 2* 10000 + 3 * 1000 + 4 * 100 + 5 * 10 + 6

2 * 10000 % 9 = 2 % 9

3 * 1000 % 9 = 3 % 9

4 * 100 % 9 = 4 % 9

5 * 10 % 9 = 5 % 9

那么x % 9 = ( 2+ 3 + 4 + 5 + 6) % 9, 注意 x = 2* 10000 + 3 * 1000 + 4 * 100 + 5 * 10 + 6

所以有: 23456 % 9 = (2 + 3 + 4 + 5 + 6) % 9

所以解法就是取各位数相加,然后对9取余,其实和第一种解法本质上是相同的,同样需要9的倍数需要特殊处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值