題目:我們把只包含因子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和第一種方案相比,第二種方案不需要在非醜數的整數上做任何計算,因此時間效率有明顯提公升。但也需要指出,第二種演算法由於需要儲存已經生成的醜數,因此需要乙個陣列,從而增加了空間消耗。如果是求第1500個醜數,將建立乙個能容納1500個醜數的陣列,這個陣列佔記憶體6kb。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)
(1)測試用例
publicview codestatic
void main(string
args)
public
void test(int
index)
", result);
console.writeline(
"-------------end-------------");
}
(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個醜數。方法一 最簡單的思路是,從...