概述
以下代码如无说明均在力扣上C++语言运行通过
题目描述
题目地址 | 给定一个非负整数 num
,反复将各个位上的数字相加,直到结果为一位数。
- 输入:38
- 输出:2
- 解释:各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。
进阶:你可以不使用循环或者递归,且在 O(1) 时间复杂度内解决这个问题吗?
题目解答
首先用常规的思路想,肯定是要用到循环的,首先计算出给定数字的各位之和,然后再看得到的结果,如果该结果不为一位数,则继续之前的步骤进行计算,否则退出循环,输出结果。问题的解答步骤可以描述如下:
- 计算完数值 num 的各位之和,并存到一个临时变量 temp 中;
- 若 temp < 10,则重复第1步;否则退出循环。
代码如下【执行用时:12ms,内存消耗:8.3MB】:
class Solution {
public:
int addDigits(int num) {
int temp=0;
while (num) {
temp += (num%10);
num /= 10; // n等于0意味着一轮算完了
if (num == 0) {
if (temp < 10) {
break;
} else {
num = temp;
temp = 0; // 一定要记得将temp归零
}
}
}
return temp;
}
};
上述代码有一个地方需要注意,第13行,一开始我没有加上第13行,这意味着temp每次计算完一轮之后都没有归零,一直在累加上次循环完后的结果,导致程序陷入死循环中。
现在来尝试不用循环解决问题。
我们来分析一下这种变换之后的数字的规律,设 n u m = a b c num = abc num=abc,即 s 1 = 100 a + 10 b + c s1 = 100a+10b+c s1=100a+10b+c,则变换之后, s 2 = a + b + c s2 = a+b+c s2=a+b+c,有 s 1 − s 2 = 99 a + 9 b = 9 ( 11 a + b ) s1-s2=99a+9b=9(11a+b) s1−s2=99a+9b=9(11a+b),差值是9的倍数, s 2 s2 s2是 s 1 s1 s1去除部分9的倍数之后的结果。若 s 2 s2 s2不为一位数,假设 s 2 = 10 x + y s2=10x+y s2=10x+y,则 s 3 = x + y s3=x+y s3=x+y,有 s 2 − s 3 = 9 x s2-s3=9x s2−s3=9x,差值也为9的倍数, s 3 s3 s3是 s 2 s2 s2去除部分9的倍数之后的结果。即,每次变换前后的差值都为9的倍数,故最后的结果总为 n u m % 9 num%9 num%9。
但是,结果为 n u m num%9 num的话,结果明显是小于9的。当num为9的时候,结果明显为9,但是依据我们前面的分析得出来是0。故可以在计算的时候进行判断,如果 n u m % 9 = = 0 num%9==0 num%9==0,则输出 9 9 9。
代码如下【执行用时:16ms,内存消耗:8.4MB】:
class Solution {
public:
int addDigits(int num) {
int temp=0;
if (num>0) {
temp = num%9;
if (temp == 0) {
temp = 9;
}
}
return temp;
}
};
也可以直接return回去,一行代码解决【执行用时:16ms,内存消耗:8.3MB】:
class Solution {
public:
int addDigits(int num) {
return num==0?0:(num%9==0?9:num%9);
}
};
事实上,在c++中,三目运算符的运算效率比if…else要低,所以还是尽量少用三目运算符。
最后
以上就是专注蜻蜓为你收集整理的LeetCode 258.各位相加的全部内容,希望文章能够帮你解决LeetCode 258.各位相加所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复