【劍指offer】醜數
轉載請註明出處:http://blog.csdn.net/ns_code/article/details/27537591
- 題目描寫敘述:
把僅僅包括因子2、3和5的數稱作醜數(Ugly Number)。比如6、8都是醜數,但14不是,由於它包括因子7。
習慣上我們把1當做是第一個醜數。求按從小到大的順序的第N個醜數。
- 輸入:
輸入包括一個整數N(1<=N<=1500)。
- 輸出:
可能有多組測試數據,對於每組數據。
輸出第N個醜數。
- 例子輸入:
3
- 例子輸出:
3
直觀的優化措施就是看能不能將時間復雜度減少到O(n),即僅僅在醜數上花時間,而不在非醜數上浪費時間。劍指offer上給的思路非常好,用O(n)的輔助空間來得到O(n)的時間復雜度。
其核心思想是:每一個醜數必定是由之前的某個醜數與2。3或5的乘積得到的,這樣下一個醜數就用之前的醜數分別乘以2,3,5。找出這三這樣的最小的而且大於當前最大醜數的值,即為下一個要求的醜數。
註意一點。這裏在九度OJ上測試,剛開始用的動態內存分配,結果爆了WA,我測試了幾組數據,包括一些大的數據,都沒問題,可是老是WA,感覺應該有可能是動態內存申請失敗的原因。由於基本肯定程序時沒錯誤的,而最多時候動態申請的內存要達到1500*4個字節。最後改成靜態數組,AC了,應該是測試系統上堆內存不夠的問題,我自己編譯器上都能夠通過。
AC代碼例如以下:
#include<stdio.h> #include<stdlib.h> int UglyNums[1500]; int Min(int a,int b,int c) { int min =(a<b)?a:b; min = (min<c)?min:c; return min; } int GetUglyNum(int index) { if(index <= 0) return 0; UglyNums[0] = 1; int CurrentIndex= 1; //當前要求的醜數的下標索引 int *p2 = UglyNums; int *p3 = UglyNums; int *p5 = UglyNums; //求每一個醜數。並保存起來 while(CurrentIndex < index) { int min = Min(2*(*p2),3*(*p3),5*(*p5)); UglyNums[CurrentIndex] = min; //每次循環都從上次的p2,p3和p5的下一個位置開始 while(2*(*p2) <= UglyNums[CurrentIndex]) ++p2; while(3*(*p3) <= UglyNums[CurrentIndex]) ++p3; while(5*(*p5) <= UglyNums[CurrentIndex]) ++p5; ++CurrentIndex; } int result = UglyNums[index-1]; return result; } int main() { int n; while(scanf("%d",&n) != EOF) printf("%d\n",GetUglyNum(n)); return 0; }
/**************************************************************
Problem: 1214
User: mmc_maodun
Language: C
Result: Accepted
Time:20 ms
Memory:920 kb
****************************************************************/
【劍指offer】醜數