問題如下:
給一個非負整數 num,反復添加所有的數字,直到結果只有一個數字。
例如:
設定 num = 38,過程就像: 3 + 8 = 11, 1 + 1 = 2。 由於 2 只有1個數字,所以返回它。
進階:
你可以不用任何的循環或者遞歸算法,在 O(1) 的時間內解決這個問題么?
初始的想法:
開始只看到了進階,要求使用O(1)的時間復雜度,因此我想了一下,既然是int型變量,那么它的范圍是-32768~32767,因此最高一共有5位數,所以O(1)算法可以直接使用五個int型變量存儲起來然后相加,最多連續相加兩次即可得到個位數,因此初始寫的代碼如下:
class Solution {
public:
int addDigits(int num) {
int a1,a2,a3,a4,a5,sum = 0;//將數據拆開后相加
a1 = num%10;
num /= 10;
a2 = num%10;
num /= 10;
a3 = num%10;
num /= 10;
a4 = num%10;
num /= 10;
a5 = num%10;
sum = a1+a2+a3+a4+a5;
a1 = sum%10;//此時最多還有兩位數有實際意義,再相加一次
sum /= 10;
a2 = sum%10;
sum = a1+a2;
a1 = sum%10;//此時最多還有兩位數有實際意義,再相加一次,必然得到個位數最終結果
sum /= 10;
a2 = sum%10;
sum = a1+a2;
return sum;
}
};
但是。。。。。。我還是Too Young Too Simple。。。
誰TM知道這個int竟然是超過五位數的啊!!!
分析錯誤:
於是乎我就查了一下資料。。。看看int究竟是怎么個一回事。。。。。
int型長度到底是幾個字節?(http://blog.sina.com.cn/s/blog_865e6dd50102vmqr.html)
在一些沒有操作系統的嵌入式計算機系統上,int的長度與處理器字長一致;有操作系統時,操作系統的字長與處理器的字長不一定一致,此時編譯器根據操作系統的字長來定義int字長:“比如你在64位機器上運行DOS16系統,那么所有for dos16的C/C++編譯器中int都是16位的;在64位機器上運行win32系統,那么所有for win32的C/C++編譯器中int都是32位的”。(CPU的“字長”是指其一條指令/一次運算可以處理的數據的最大寬度。
所以說int類型並不一定只有4位或者兩位。。。。因此要考慮到數字特別大的情況。。。。。。。。
改正錯誤:
因此我還是用循環函數吧。。。。。。代碼如下
class Solution {
public:
int addDigits(int num) {
int i,sum = 0;
while(1)
{
while(num != 0)
{
sum += num%10;
num /= 10;
}
if(sum >= 10)
{
num = sum;
sum = 0;
}
else
break;
}
return sum;
}
};
這次問題成功解決了。
問題:
那么究竟用什么方法才能達到O(1)的時間復雜度呢?這個問題在我詳細的學習算法后再進行解答。