問(wèn)題:
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?
大意:
給一個(gè)非負(fù)數(shù),重復(fù)地加其中的數(shù)字知道最后只有一個(gè)數(shù)字。
比如說(shuō):
給出數(shù)字38匹摇,過(guò)程類(lèi)似于:3+8=11,1+1=2.直到2只有一個(gè)數(shù)字了带膀,就返回它勉抓。
繼續(xù):
你能不能不用任何循環(huán)滥沫、遞歸來(lái)在O(1)的時(shí)間復(fù)雜度中完成它?
思路一:
首先想到的就是循環(huán)谣殊,對(duì)于一個(gè)數(shù)字凛俱,循環(huán)將其除以10的余數(shù)加起來(lái)紊馏,直到其是個(gè)位數(shù)。加完一次后判斷是不是沒(méi)數(shù)字了蒲犬,也就是等于0朱监,如果還大于0,說(shuō)明還有多個(gè)數(shù)字原叮,那就再進(jìn)行同樣的操作赫编。
代碼一(c++):
class Solution {
public:
int addDigits(int num) {
int sum = 0;
while (num > 0) {
sum += num % 10;
num = num / 10;
}
if (sum > 9) return addDigits(sum);
else return sum;
}
};
思路二:
既然題目里也鼓勵(lì)我們繼續(xù)思考不用循環(huán)的方式,那就一定是有規(guī)律可循奋隶。我們可以簡(jiǎn)單地列一下:
數(shù)字 | 結(jié)果 |
---|---|
0 | 0 |
1 | 1 |
2 | 2 |
3 | 3 |
4 | 4 |
5 | 5 |
6 | 6 |
7 | 7 |
8 | 8 |
9 | 9 |
10 | 1 |
11 | 2 |
12 | 3 |
13 | 4 |
14 | 5 |
15 | 6 |
16 | 7 |
17 | 8 |
18 | 9 |
19 | 1 |
20 | 2 |
21 | 3 |
就列這么多了擂送,我們可以發(fā)現(xiàn),結(jié)果除了第一個(gè)0以外达布,都在19之間循環(huán)团甲。而且可以發(fā)現(xiàn),其除以9的余數(shù)黍聂,為0時(shí),對(duì)應(yīng)的結(jié)果是9身腻,而不為0時(shí)产还,余數(shù)等于對(duì)應(yīng)的結(jié)果,那么代碼就呼之欲出啦
代碼二(c++):
class Solution {
public:
int addDigits(int num) {
return num % 9 == 0 ? (num == 0 ? 0 : 9) : num % 9;
}
};
合集:https://github.com/Cloudox/LeetCode-Record