來源:LeetCode 258 Add Dights
Question: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?
分析:
數字根(digital root)是自然數的一種性質,即每個自然數都有一個數字根。數根是將一自然數的各個位數相加(即橫向相加),若加完后的值大於等於10的話,則繼續將各位數進行橫向相加直到其值小於10為止。例如54817的數根為7,因為5+4+8+1+7=25,25大於10則再加一次,2+5=7,7小於10,則7為54817的數字根。
上面問題即是求一個非負整數的數字根。很容易想到下面這種方法解決問題:
#include<stdio.h> #include<assert.h> int addDigits(int num) { int temp=0; while(num>=10) { temp+=(num%10); num/=10; } temp+=num; //不要忽略最高位數 num=temp; if(num>=10) { num=addDigits(num);//num仍大於10,則遞歸調用addDights函數 } return num; } int main() { int num; scanf("%d",&num); assert(num>=0); //非負整數斷言 printf("%d\n",addDigits(num)); return 0; }
注意題目的延伸:要求我們不使用循環/遞歸復雜度O(1)
這里用到一個求數字根的公式:
上述公式的文字表述為:0的數字根為0,9的倍數的數字根為9,其他自然數的數字根為其除以9的余數。證明過程點擊這里
上述公式可簡單表述為:
所以對於延伸的問題我們可以寫出解決方法如下:
#include<stdio.h> #include<assert.h> int addDigits(int num) { return 1+(num-1)%9; //直接調用公式 } int main() { int num; scanf("%d",&num); assert(num>=0); //非負整數斷言 printf("%d\n",addDigits(num)); return 0; }