面試題49:醜數
一、題目描述
我們把只包含質因子2、3和5的數稱作醜數(Ugly Number)。求按從小到大的順序的第N個醜數。
例如6、8都是醜數,但14不是,因爲它包含質因子7。 習慣上我們把1當做是第一個醜數。
二、問題分析
判斷一個數是不是醜數,最容易想到的方法就是讓這個數不斷除以2,3,5。
對於第N個醜數,只要從1開始,依次判斷每個數是不是醜數,如果是,則相應的序號加1,直到序號爲N,就是我們要的醜數了。但是這種方法時間效率很,通常面試官不會滿意這樣的答案。因此我們需要一個時間複雜度更低的解法。
換個思路,我們只求醜數,不要去管非醜數。每個醜數必然是由小於它的某個醜數乘以2,3或5得到的,這樣我們把求得的醜數都保存下來,用之前的醜數分別乘以2,3,5,找出這三這種最小的並且大於當前最大丑數的值,即爲下一個我們要求的醜數。這種方法用空間換時間,時間複雜度爲O(n)。
三、問題解答
public int GetUglyNumber(int index) {
if(index <= 0) {
return 0;
}
if(index == 1) {
return 1;
}
int t2 = 0, t3 = 0, t5 = 0;
int [] res = new int[index];
res[0] = 1;
for(int i = 1; i<index; i++){
res[i] = Math.min(res[t2]*2, Math.min(res[t3]*3, res[t5]*5));
if(res[i] == res[t2]*2) t2++;
if(res[i] == res[t3]*3) t3++;
if(res[i] == res[t5]*5) t5++;
}
return res[index-1];
}