《劍指offer》 34 醜數的判斷與查詢

2022-03-17 09:26:05 字數 2065 閱讀 1287

題目:我們把只包含因子2,3,5的數稱為醜數(ugly number)。求按從小到大的順序的第1500個醜數。

例如6,8都是醜數,但14不是,因為它包含因子7.習慣上我們把1當作第乙個醜數。

方案一:所謂乙個數m是n的因子的意思是n能被m整除。那麼根據醜數的定義,醜數只能被2,3,5整除,如果乙個數能被2整除我們就連續除以2,如果能被3整除我們就連續除以3,如果能被5整除,我們就連續除以5。若最後的結果為1,那麼就是醜數,否則就不是。時間複雜度為o(n)(n為第n個醜數以前的所有遞增資料)。

方案二:o(n)效率(n為醜數的個數)。由於方案一中的方法需要對非醜數的資料進行除法和取餘操作,所以效率不是很高,效率會隨著數目的增大而變大。這種方案主要是用o(n)的空間換來了時間效率。我們主要避免了方案一中的非醜數的計算過程。該方案只需要計算醜數,而不用再非醜數上花費時間。

根據醜數的定義我們知道,醜數是乙個醜數*(2,3,5)得到的(1除外),因此我們可以建立乙個陣列,裡面的資料都是儲存著醜數資料。這種思路的關鍵在於怎麼確保陣列裡面的醜數是排好序的,因為我們得到的是第n個醜數,所以確保醜數的順序是該方案的關鍵所在。我們假設陣列中已經有若干個醜數,排好序後存在陣列中。我們把現有的最大醜數記做m。現在我們來生成下乙個醜數,該醜數肯定是前面某乙個醜數乘以2、3或者5的結果。我們首先考慮把已有的每個醜數乘以2。在乘以2的時候,能得到若干個結果小於或等於m的。由於我們是按照順序生成的,小於或者等於m肯定已經在陣列中了,我們不需再次考慮;我們還會得到若干個大於m的結果,但我們只需要第乙個大於m的結果,因為我們希望醜數是按從小到大順序生成的,其他更大的結果我們以後再說。我們把得到的第乙個乘以2後大於m的結果,記為m2。同樣我們把已有的每乙個醜數乘以3和5,能得到第乙個大於m的結果m3和m5。那麼下乙個醜數應該是m2、m3和m5三個數的最小者。

前面我們分析的時候,提到把已有的每個醜數分別都乘以2、3和5,事實上是不需要的,因為已有的醜數是按順序存在陣列中的。對乘以2而言,肯定存在某乙個醜數t2,排在它之前的每乙個醜數乘以2得到的結果都會小於已有最大的醜數,在它之後的每乙個醜數乘以2得到的結果都會太大。我們只需要記下這個醜數的位置,同時每次生成新的醜數的時候,去更新這個t2。對乘以3和5而言,存在著同樣的t3和t5。

方案一具體實現**:

#include

using namespace std;

#include

bool isugly(int number)

while(0==number%2)

number/=2;

while(0==number%3)

number/=3;

while(0==number%5)

number/=5;

return 1==number?true:false;

int getugly(int index)

if(0>=index)

return 0;

int count=0;

int number=0;

while(count(end_time-start_time)/clocks_per_sec*1000<

system("pause");

return 0;

執行結果:

前100個醜數為:

方案二具體實現的**:

#include

using namespace std;

int min(int number1,int number2,int number3)

return ((number1=index)

return 0;

int *puglynumbers=new int[index];//輔助空間;

puglynumbers[0]=1;//第乙個數的值;

int nextuglyindex=1;//醜數的個數計數;

int *pmultiply2=puglynumbers;

int *pmultiply3=puglynumbers;

int *pmultiply5=puglynumbers;

while(nextuglyindex執行結果:

從結果可以看出,方案二用時2ms,而方案一用時81264ms,這個提公升是非常有效果的!數越大效率提公升的越明顯!

劍指offer 34 醜數

只包含因子2 3 5的數稱為醜數。方法1 逐個判斷每個整數是不是醜數 方法2 建立陣列儲存已經找到的醜數,用空間換時間的方法 每乙個醜數都是前面的醜數乘以2 3 5得到的 已有醜數中最大醜數為m,下乙個醜數應該是已知醜數分別乘以2 3 5的第乙個大於m的數,記錄,每個乘以2 3 5第乙個大於m的位置...

劍指Offer 34 醜數

把只包含因子2 3和5的數稱為醜數,求從小到大的順序的第1500個數。1是第乙個醜數。乙個醜數可以表示成2m3 n5 k2 m3 n5 k 2m3n5k 其中,m n k為自然數zzz。醜數從小到大的順序其實是m n k這三個數中的其中乙個數加一。生成過程 陣列res初始化,儲存了第乙個元素res ...

劍指offer 34 醜數

把只包含質因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含質因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。看到這個問題的時候可以這樣想 解題思路 因為乙個醜數隻包含質因子2 3和5,也就是說乙個醜數一定由另乙個醜數乘以2或者乘以...