劍指offer面試題 34 醜數

2021-08-03 14:18:48 字數 1436 閱讀 8500

題目描述

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

思路分析:

思路一:逐個判斷每個整數是不是醜數的解法,直觀但不高效(牛客網測試超時)

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

最大的問題是每個整數都需要計算。即使乙個數字不是醜數,我們還是需要對它做求餘和除法操作。因此該演算法的時間效率不夠高,面試官也不會就此滿足。

思路二:建立陣列儲存已找到的醜數,用空間換時間的解法

前面的演算法之所以效率低,很大程度上是因為不管乙個數是不是醜數,我們對它都要作計算。接下來我們試著找到一種只要計算醜數的方法,而不在非醜數的整數上浪費時間。根據醜數的定義,

醜數應該是另乙個醜數乘以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。

class solution 

/*方法一:尷尬,超時。

int getuglynumber_solution(int index)

return i-1;

}bool ifugly(int i)

*/};

劍指Offer 面試題34 醜數

我們把只包含因子2 3和5的數成為醜數,求按從小到大的順序的第1500個醜數。例如6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當做第乙個醜數。分析 逐個判斷整數是不是醜數,直觀但是效率低下。根據醜數的定義,醜數只能被2 3和5整除,也就是說乙個數能被2整除,我們把它連續除以2 如果能...

劍指offer 面試題34 醜數

劍指offer 面試題34 醜數 題目 把只包含質因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含質因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。思路 給乙個陣列存放當前已有的醜數,這些醜數都是按順序存放的,每次計算新的醜數時,...

劍指offer 面試題34 醜數

題目 把只包含因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。思路 需要注意的是,下乙個醜數可能是其中兩個或三個數衍生的,比如在生成6時,2衍生的是6,3在那個時候衍生的恰好也是6....