題目描述把只包含質因子2、3和5的數稱作醜數(ugly number)。例如6、8都是醜數,但14不是,因為它包含質因子7。 習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。
通俗易懂的解釋:【考點】數學題首先從醜數的定義我們知道,乙個醜數的因子只有2,3,5,那麼醜數p = 2 ^ x * 3 ^ y * 5 ^ z,xyz是任意正整數。換句話說乙個醜數一定由另乙個醜數乘以2或者乘以3或者乘以5得到,那麼我們從1開始乘以2,3,5,就得到2,3,5三個醜數,在從這三個醜數出發乘以2,3,5就得到4,6,10,6,9,15,10,15,25九個醜數,我們發現這種方法會得到重複的醜數,而且我們題目要求第n個醜數,這樣的方法得到的醜數也是無序的。那麼我們可以維護三個佇列:
(1)醜數陣列: 1
乘以2的佇列:2
乘以3的佇列:3
乘以5的佇列:5
選擇三個佇列頭最小的數2加入醜數陣列,同時將該最小的數乘以2,3,5放入三個佇列;
(2)醜數陣列:1,2
乘以2的佇列:4
乘以3的佇列:3,6
乘以5的佇列:5,10
選擇三個佇列頭最小的數3加入醜數陣列,同時將該最小的數乘以2,3,5放入三個佇列;
(3)醜數陣列:1,2,3
乘以2的佇列:4,6
乘以3的佇列:6,9
乘以5的佇列:5,10,15
選擇三個佇列頭里最小的數4加入醜數陣列,同時將該最小的數乘以2,3,5放入三個佇列;
(4)醜數陣列:1,2,3,4
乘以2的佇列:6,8
乘以3的佇列:6,9,12
乘以5的佇列:5,10,15,20
選擇三個佇列頭里最小的數5加入醜數陣列,同時將該最小的數乘以2,3,5放入三個佇列;
(5)醜數陣列:1,2,3,4,5
乘以2的佇列:6,8,10,
乘以3的佇列:6,9,12,15
乘以5的佇列:10,15,20,25
選擇三個佇列頭里最小的數6加入醜數陣列,但我們發現,有兩個佇列頭都為6,所以我們彈出兩個佇列頭,同時將12,18,30放入三個佇列;
……………………
疑問:1.為什麼分三個佇列?
醜數陣列裡的數一定是有序的,因為我們是從醜數陣列裡的數乘以2,3,5選出的最小數,一定比以前未乘以2,3,5大,同時對於三個佇列內部,按先後順序乘以2,3,5分別放入,所以同乙個佇列內部也是有序的;
2.為什麼比較三個佇列頭部最小的數放入醜數陣列?
因為三個佇列是有序的,所以取出三個頭中最小的,等同於找到了三個佇列所有數中最小的。
實現思路:
我們沒有必要維護三個佇列,只需要記錄三個指標顯示到達哪一步;「|」表示指標,arr表示醜數陣列;
有了指標的位置,就能直接算出佇列中的任意乙個數的值。
程式中是p2 p3 p5從0開始計數,如果有加入到醜數陣列中的,就要把指標往後移動一位。
(1)醜數陣列:1
|2|3
|5目前指標指向0,0,0,佇列頭arr[0] * 2 = 2, arr[0] * 3 = 3, arr[0] * 5 = 5
(2)醜數陣列:1 2
2 |4
|3 6
|5 10
目前指標指向1,0,0,佇列頭arr[1] * 2 = 4, arr[0] * 3 = 3, arr[0] * 5 = 5
(3)醜數陣列:1 2 3
2 |4 6
3 |6 9
|5 10 15
目前指標指向1,1,0,佇列頭arr[1] * 2 = 4, arr[1] * 3 = 6, arr[0] * 5 = 5
………………
class
solution
return newnumber;}}
;
差缺補漏:
不能直接寫min(a,b,c),那麼換個思路先比較其中2個即可min(a,min(b,c))
有時候指標用int代替,可視性更好
找出規律,正確窮舉出所有值,也許也是一種很好的演算法
劍指offer 面試題49 醜數
我們把只包含因子2 3 和 5 的數稱作醜數 ugly number 求按照從小到大的順序的第1500個醜數。例如,6 8都是醜數,但是14不是,因為它包含因子7。習慣上我們把1當做第乙個醜數。有空再補上 public class 49 uglynumber return uglynumbers i...
《劍指offer》面試題49 醜數
設計乙個演算法,找出只含素因子2,3,5 的第 n 小的數。符合條件的數如 1,2,3,4,5,6,8,9,10,12 思路 思路1 從1開始遞增,依次判斷每個數是否是醜數,不夠高效 思路2 思路1之所以效率低,比較關鍵的一點是遍歷的每乙個數字都進行醜數判斷。思路2不是去判斷醜數,而是計算出醜數 因...
劍指offer 面試題49 醜數
面試題 劍指offer 題目解答 把只包含質因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含質因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。首先我們能想到的方法就是,迴圈遍歷,對每乙個數字進行判斷,如果是醜數那麼數量加一,直到等...