劍指offer 33 醜數

2021-09-02 23:34:55 字數 1857 閱讀 5454

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

通俗易懂的解釋:

首先從醜數的定義我們知道,乙個醜數的因子只有2,3,5,那麼醜數p = 2 ^ x * 3 ^ y * 5 ^ z,換句話說乙個醜數一定由另乙個醜數乘以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表示醜數陣列;

arr 1

|2|3

|5目前指標指向0,0,0,佇列頭arr[0] * 2 = 2, arr[0] * 3 = 3, arr[0] * 5 = 5

arr 1,2

2 |4

|3 6

|5 10

目前指標指向1,0,0,佇列頭arr[1] * 2 = 4, arr[0] * 3 = 3, arr[0] * 5 = 5

arr 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

………………

public

class

solution33

return newnum;

}public

static

void

main

(string[

] args)

}

《劍指offer》33 醜數

把只包含質因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含質因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。c 實現 class solution return a index 1 python實現 coding utf 8 cl...

劍指offer33 醜數

題目描述 把只包含質因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含質因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。這裡講解的很詳細了。coding utf 8 class solution def getuglynumber ...

劍指offer 33 醜數

把只包含質因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含質因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。時間限制 1秒 空間限制 32768k 熱度指數 209207 本題知識點 陣列 1.窮舉 超時 class soluti...