醜數Ugly Number查詢演算法

2021-06-09 02:17:50 字數 2530 閱讀 9666

我們把只包含因子2、3和5的數稱作醜數(ugly number)。例如6、8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第1500個醜數

下面是一道在網路上廣為流傳的面試題,據說google曾經採用過這道題。

所謂乙個數m是另乙個數n的因子,是指n能被m整除,也就是n % m == 0。根據醜數的定義,醜數只能被2、3和5整除。也就是說如果乙個數如果它能被2整除,我們把它連續除以2;如果能被3整除,就連續除以3;如果能被5整除,就除以連續5。如果最後我們得到的是1,那麼這個數就是醜數,否則不是。

基於前面的分析,我們可以寫出如下的函式來判斷乙個數是不是醜數:

01boolisugly(intnumber)

02

接下來,我們只需要按順序判斷每乙個整數是不是醜數,即:

01intgetuglynumber_solution1(intindex)

02

14}

15returnnumber;

16}

我們只需要在函式getuglynumber_solution1中傳入引數1500,就能得到第1500個醜數。該演算法非常直觀,**也非常簡潔,但最大的問題我們每個整數都需要計算。即使乙個數字不是醜數,我們還是需要對它做求餘數和除法操作。因此該演算法的時間效率不是很高。

接下來我們換一種思路來分析這個問題,試圖只計算醜數,而不在非醜數的整數上花費時間。根據醜數的定義,醜數應該是另乙個醜數乘以2、3或者5的結果(1除外)。因此我們可以建立乙個陣列,裡面的數字是排好序的醜數。裡面的每乙個醜數是前面的醜數乘以2、3或者5得到的。

這種思路的關鍵在於怎樣確保陣列裡面的醜數是排好序的。我們假設陣列中已經有若干個醜數,排好序後存在陣列中。我們把現有的最大醜數記做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。

有了這些分析,我們不難寫出如下的**:

view source

print?

01intgetuglynumber_solution2(intindex)

02

23intugly = puglynumbers[nextuglyindex - 1];

24deletepuglynumbers;

25returnugly;

26}

27intmin(intnumber1,intnumber2,intnumber3)

28

和第一種思路相比,這種演算法不需要在非醜數的整數上做任何計算,因此時間複雜度要低很多。感興趣的讀者可以分別統計兩個函式getuglynumber_solution1(1500)和getuglynumber_solution2(1500)的執行時間。當然我們也要指出,第二種演算法由於要儲存已經生成的醜數,因此需要乙個陣列,從而需要額外的記憶體。第一種演算法是沒有這樣的記憶體開銷的。

計算第N個醜數 Ugly Number

題目描述 包含質因子2 3和5的數稱作醜數。例如6 8都是醜數,但14不是,因為它包含質因子7。習慣上我們把1當做是第乙個醜數。按從小到大的順序求第n個醜數 題目分析 質因子包含2 3 5三個中任意乙個或者多個 而且題目明確給出1為最小的醜數 因此可以從1開始,對後面的數依次乘以2 3 5.比如乙個...

Python 查詢第n個醜數

質因數只包含2 3 5中的乙個或多個的數稱為醜數 對任意的乙個醜數 除第乙個醜數 1 外 ui,必定存在乙個ut ui,使得 ui ut 2 或 ut 3 或 ut 5,若不成立則 1.ui 2 3 5 不等於 0,ui 不是整數 2.ui 2 3 5 等於 0,ui 2 3 5 是醜數則,ui 也...

超級醜數 用堆查詢解決

利用堆排序很容易進行查詢 質數又稱素數。乙個大於1的自然數,除了1和它自身外,不能被其他自然數整除的數叫做質數 否則稱為合數。質因數 素因數或質因子 在數論裡是指能整除給定正整數的質數。除了1以外,兩個沒有其他共同質因子的正整數稱為互質。因為1沒有質因子,1與任何正整數 包括1本身 都是互質 把只包...