1. 程式人生 > >【劍指offer】醜數

【劍指offer】醜數

accep org sof 動態內存 sca 時間 sta ren stream

轉載請註明出處: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
思路:最簡單的方法就是先通過將一個數不斷除以2,3,5來判定該數是不是醜數,而後在從1開始。依次往後推斷每一個數是不是醜數,並記下醜數的個數,這樣當計算的個數為給定值時。便是須要求的第n個醜數,這樣的方法的時間復雜度為O(k)。這裏的k為第n個醜數的大小,比方第1500個醜數的大小為859963392,那麽就須要推斷859963392次。時間效率非常低。

直觀的優化措施就是看能不能將時間復雜度減少到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】醜數