0.简介
记录LeetCode刷题过程,每篇分为四部分,题目描述、解题思路、参考代码、复杂度分析
如有疑问欢迎讨论,GitHub地址:https://github.com/LoneRanger0504/LeetCode
1.题目描述
给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。
示例1:
输入: 38
输出: 2
解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。
进阶:
你可以不使用循环或者递归,且在 O(1) 时间复杂度内解决这个问题吗?
2.解题思路
(1)最简单最直接的解法,暴力循环,当num >= 10时,一直取个位数,再与剩下数字相加,得到新的num
(2)O(1)解法:既然提到O(1)解法,自然要想,什么情况下会是O(1)呢,既然是一道跟数学有关的题,那么想到从数学角度出发。解题思路类似于小学找规律,首先,0-9这些个位数,直接返回自己,从10-18,返回1-9,从19-27,返回1-9,从28-36,返回1-9,以此类推,我们发现,只要从1开始,除了9的倍数意外,对应的返回值就等于这个数 % 9。当num是9的倍数的时候,并不返回0,而是返回9。
即整体思路为:判断 num % 9的余数是否为0 如果余数不为0,直接返回该余数 ;如果余数为0,判断num是否为0,num为0返回0,num不为0返回9
3.参考代码
```
#(1)暴力循环
while num >= 10:
remainder = num % 10
quotient = (num - remainder) // 10
num = remainder + quotient
return num
#(2)根据规律,O(1)解法
if num % 9 == 0:
if num == 0:
return 0
else:
return 9
else:
return num % 9
```
4.复杂度分析
(1)循环解法时间复杂度自然是O(N),N为给定数字num的位数,空间复杂度O(1)
(2)解法2只需要找到规律直接计算,时间复杂度O(1),空间复杂度也为O(1)