劍指Offer面試題 29 醜數

2022-01-11 09:44:33 字數 3077 閱讀 5138

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

使用遍曆法求第k個醜數,從1開始遍歷,如果是醜數則count++,直到count=k為止。那麼如何判斷醜數呢?根據醜數的定義,醜數只有2,3,5這三個因子,那麼我們就拿數字除以這三個因子。具體演算法如下:

step1.如果乙個數能夠被2整除,那麼讓他繼續除以2;

step2.如果乙個數能夠被3整除,那麼讓他繼續除以3;

step3.如果乙個數能夠被5整除,那麼讓他繼續除以5;

step4.如果最後這個數變為1,那麼這個數就是醜數,否則不是。

根據以上演算法實現**如下:

public

int getuglynumber(int

index)

int number = 0

;

int uglycount = 0

;

while (uglycount

}return

number;

}private

bool isugly(int

number)

while (number % 3 == 0

)

while (number % 5 == 0

)

return number == 1 ? true : false

; }

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

根據醜數的定義,我們可以知道醜數可以由另外乙個醜數乘以2,3或者5得到。因此我們可以建立乙個陣列,裡面的數字是排好序的醜數,每乙個醜數都是前面的醜數乘以2,3或者5得到的。

我們把得到的第乙個醜數乘以2以後得到的大於m的結果記為m2。同樣,我們把已有的每乙個醜數乘以3和5,能得到第乙個大於m的結果m3和m5。那麼m後面的那乙個醜數應該是m2,m3和m5當中的最小值:min(m2,m3,m5)。比如將醜數陣列中的數字按從小到大乘以2,直到得到第乙個大於m的數為止,那麼應該是2*2=4m,所以m2=6。同理,m3=6,m5=10。所以下乙個醜數應該是6。

根據以上思路實現**如下:

public

int getuglynumber(int

index)

int uglynumbers = new

int[index];

uglynumbers[

0] = 1

;

int nextuglyindex = 1

;

int multiply2 = 0

;

int multiply3 = 0

;

int multiply5 = 0

;

int min = 0

;

while (nextuglyindex

while (uglynumbers[multiply3] * 3

<=uglynumbers[nextuglyindex])

while (uglynumbers[multiply5] * 5

<=uglynumbers[nextuglyindex])

nextuglyindex++;

}int result = uglynumbers[index - 1

]; uglynumbers = null

;

return

result;

}private

int min(int num1, int num2, int

num3)

和第一種方案相比,第二種方案不需要在非醜數的整數上做任何計算,因此時間效率有明顯提公升。但也需要指出,第二種演算法由於需要儲存已經生成的醜數,因此需要乙個陣列,從而增加了空間消耗。如果是求第1500個醜數,將建立乙個能容納1500個醜數的陣列,這個陣列佔記憶體6kb。

(1)測試用例

public

static

void main(string

args)

public

void test(int

index)

", result);

console.writeline(

"-------------end-------------");

}

view code

(2)測試結果

這裡我們使用兩種解決方案來求第1500個醜數,通過下面的可以清楚地看到兩種方案的響應時間。(這裡借助老趙的codetimer類來進行時間效率的監測)

(1)一一遍曆法:65秒,我等得花兒都謝了

(2)空間換時間法:4毫秒,迅雷不及掩耳

由對比可以看出,乙個簡單的優化,再通過6kb的空間換取了巨大的時間效率,在實際開發中是乙個值得實踐的解決思路(當然,事先得權衡一下利弊)。

出處:

劍指Offer 面試題34 醜數

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

劍指offer面試題 34 醜數

題目描述 把只包含因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。思路分析 思路一 逐個判斷每個整數是不是醜數的解法,直觀但不高效 牛客網測試超時 所謂乙個數m是另乙個數n的因子,是...

劍指offer面試題目 醜數

把只包含因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。輸入 輸入包括乙個整數n 1 n 1500 輸出 可能有多組測試資料,對於每組資料,輸出第n個醜數。方法一 最簡單的思路是,從...