leetcode刷题记录-258. 各位相加

396 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

前言

今天的题目为简单,虽然题目确实简单,但是题目要求的进阶做法就没有那么简单,稍微需要涉及一点数学知识。

每日一题

今天的每日一题 258. 各位相加,难度为简单

  • 给定一个非负整数 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) 时间复杂度内解决这个问题吗?

题解

模拟

首先题目要求把一个数字的每一位都加起来,一直重复知道结果小于10,那么很简单的模拟思路,只要将 num 余 10 就能够得到当前的个位数,然后将 num / 10 并且向下取整,这时候的各位就变成了了之前的十位,重复取余的过程,一直到 num 变为 0,然后我们去判断得到的所有个位数加起来是不是小于 10,是的话就为答案,不是的话继续重复上面的过程。

/**
 * @param {number} num
 * @return {number}
 */
 var addDigits = function(num) {
    while (num >= 10) {
        let sum = 0;
        while (num > 0) {
            sum += num % 10;
            num = Math.floor(num / 10);
        }
        num = sum;
    }
    return num;
};

image.png

数学思路

这道题的难点主要是进阶的地方,如何去用 O(1) 的时间复杂度来完成这道题,这种一般都是只能用到数学方面的思维来解题,也就是去找规律。

给我们的数字 num,我们可以看出两部分,一部分是个位数部分,一部分是除了个位数的其他部分,那么这时候我们可以关注一个点,那就是除了个位数的其他部分,比方说 240 那么它十位和百位相加,就是它余去9剩下的值。

这样挺好理解的,比方说 240 那么就有 24 个 10,每一个10余9,那么就有 24 个 1,在这其中,2 又是十位数,又可以余去9,剩下的就是 2,那么就是 2 和 4,也就是题目需要我们求的。

加上个位数也是一个道理,每次都是除去个位数不算,但是十位百位千位都是可以被 10 等分,每一个位置上的数就是一等分,到最后也就会等于与 9 去余的那个数。

image.png

结合上图我们也能够更好地看出来一个规律,就下去我们就是要对特殊情况进行处理,也就是刚好能被9整除的情况以及0这种情况

/**
 * @param {number} num
 * @return {number}
 */
 var addDigits = function(num) {
    if(num == 0){
        return 0
    }
    if(num%9 == 0){
        return 9
    }
    return num%9
};

image.png