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;
};
数学思路
这道题的难点主要是进阶的地方,如何去用 O(1) 的时间复杂度来完成这道题,这种一般都是只能用到数学方面的思维来解题,也就是去找规律。
给我们的数字 num,我们可以看出两部分,一部分是个位数部分,一部分是除了个位数的其他部分,那么这时候我们可以关注一个点,那就是除了个位数的其他部分,比方说 240 那么它十位和百位相加,就是它余去9剩下的值。
这样挺好理解的,比方说 240 那么就有 24 个 10,每一个10余9,那么就有 24 个 1,在这其中,2 又是十位数,又可以余去9,剩下的就是 2,那么就是 2 和 4,也就是题目需要我们求的。
加上个位数也是一个道理,每次都是除去个位数不算,但是十位百位千位都是可以被 10 等分,每一个位置上的数就是一等分,到最后也就会等于与 9 去余的那个数。
结合上图我们也能够更好地看出来一个规律,就下去我们就是要对特殊情况进行处理,也就是刚好能被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
};