普通思路就是數(shù)字拆分字符串再轉(zhuǎn)數(shù)字一一相加,并遞歸了。代碼如下
function addDigits(num) { if (num < 10) { return num; } var result = 0; (num + '').split('').forEach(item => { result = parseInt(item, 10) + result }); return addDigits(result); }
提交查看結(jié)果:
運(yùn)行時(shí)間還屬于中等偏長(zhǎng)的干茉,時(shí)間復(fù)雜度也是O(n)论颅;
Follow up:
Could you do it without any loop/recursion in O(1) runtime?
嘗試用eval,但是提示eval壞處大镜雨,不讓用...
吾輩沒(méi)有不同常人的大腦嫂侍,所以只能各種情況枚舉,猜想其中是否有什么不得了的規(guī)矩冷离,可以讓人一下子就能得到答案吵冒?
addDigits(23) //=>5
addDigits(2019) //=>3
addDigits(666) //=>9
addDigits(987654321) //=>9
我們發(fā)現(xiàn),這些數(shù)返回值都是0-9的整數(shù)(廢話)西剥,假設(shè)我認(rèn)為他們一定又什么規(guī)(yin)律(mou)痹栖,那么損失的數(shù)字(初始值與結(jié)果的差)是不是有什么規(guī)律?
addDigits(23) //=>5 =>18/9=2
addDigits(2019) //=>3 =>2016/9=224
addDigits(666) //=>9 =>657/9=73
addDigits(987654321) //=>9 =>懶得算了...
哇瞭空,也就是說(shuō) result = num%9???
987654321%9 //=>0???
由于num恰好是9的倍數(shù)的情況揪阿,所以要進(jìn)行適當(dāng)?shù)奶幚恚罱K我們結(jié)果是
function addDigits(num) { if (num < 10) { return num; } else { return num % 9 || 9; } }
哈哈咆畏,應(yīng)該不錯(cuò)了吧南捂,看看結(jié)果。
注:這里第一個(gè)if判斷應(yīng)該是<1,提交后beats 80.37%旧找。(原來(lái)判斷數(shù)值大小會(huì)差別那么多溺健?)
?钮蛛?鞭缭?前面還這么多人...leetcode不愧都是些厲害的大神...于是我點(diǎn)開(kāi)discuss看看還有什么不得了的東西。
我們來(lái)看看view數(shù)排名第一的topic魏颓,看id估計(jì)還是國(guó)人...
那么我們?cè)偎伎歼@個(gè)公式(1 +(n-1)%9)怎么來(lái)呢...我們?cè)偎伎剂肜保瑢?duì)于余數(shù)在1-8之間,直接返回即可甸饱,但是余數(shù)是0的沦童,有兩種可能0和9的倍數(shù)仑濒,那么如何區(qū)分這兩種可能?但是除以9的余數(shù)除了1-8和0之外還有別的可能嗎偷遗?墩瞳?
沒(méi)錯(cuò),就是負(fù)數(shù)氏豌。也就是說(shuō)我們要至少引進(jìn)一個(gè)負(fù)數(shù)的結(jié)果矗烛,那么就要用到減法了。
將 x +(num - x)% 9箩溃。x屬于正整數(shù)瞭吃。
那我隨便來(lái)個(gè)簡(jiǎn)單的x,就取值為1吧涣旨,來(lái)提交試試歪架。
function addDigits(num) { return 1 + (num - 1) % 9; }
喵喵喵?寫(xiě)不下去了...裝逼失敗...