題目描述
把只包含因子2、3和5的數稱作醜數(ugly number)。例如6、8都是醜數,但14不是,因為它包含因子7。 習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。
這一題我想了很久,自己想的方法時間複雜度都太高,所有都超時了,導致一上午都在糾結這個問題,最後看別人的答案才知道大神都是怎麼解決這個問題的,仔細想想,還是自己的演算法基礎不太好。好了,廢話不多說,直接上思路。
遍曆法:時間效率低下
使用遍曆法求第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 < index)
}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 < index)
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。
劍指offer 醜數
把只包含因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。分析 參考程式設計師面試金典 偽 如下 1 初始化array和佇列 q2 q3 q5 2 將1插入array 3 分別將1 2...
劍指Offer 醜數
我們把只包含因子 2 3 和 5 的數稱作醜數 ugly number 求按從小 到大的順序的第 1500 個醜數。例如 6 8都是醜數,但 14 不是,它包含因子 7。習慣上我們把 1當做第乙個醜數。解法一 逐一判斷是否是醜數,簡單但是不夠高效 數字n是數字m的因子說明m n 0。醜數的因子只有2...
劍指offer 醜數
把只包含因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。分析 為了保證時間達到要求,可以將所求得的醜數都儲存在陣列中,然後再取出。前面的醜數乘以2 3或5中的最小的乙個是下乙個醜數。...