題目描述:我們把只包含質因子 2、3 和 5 的數稱作醜數(ugly number)。求按從小到大的順序的第 n 個醜數。
示例1:
輸入: n = 10
輸出: 12
解釋: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 個醜數。
解題思路:1、動態規劃:
常規的思路是從小遍歷醜數,並根據前面的醜數生成後面的醜數,可以採用三個指標的方法:p2、p3、p5。p2指向的數字乘以2可以得出乙個醜數,p3指向的數字乘以3可以得出乙個醜數,p5指向的數字乘以5可以得出乙個醜數,然後選取這三個醜數的最小的乙個數字作為下乙個醜數,如果第k個醜數是由p2指向的數字乘以2生成的,那麼p2++,因為前面0-p2個醜數乘以2不可能生成比第k個醜數更打的醜數了,p3和p5同理。
狀態轉移方程:根據上述可以得出狀態轉移方程:dp[i] = min(dp[p2] x 2, dp[p3] x 3, dp[p5] x 5)
,同時第乙個醜數為1,因此dp[0] = 1
,而第n個醜數就是dp[n - 1]。
注:在判斷下乙個醜數是由p2、p3還是p5生成的時候要分別判斷,因為有可能存在p2、p3和p5生成醜數一樣的情況,這種情況p2、p3和p5都需要加1,否則會出現生成相同醜數的情況。
2、小根堆:
由於任意醜數乘以2,3,5都是醜數,因此可以從小遍歷醜數,並乘以2,3,5生成更大的醜數。由於求的是第n小的醜數,因此可以使用乙個小根堆來儲存醜數,然後每次計數彈出乙個醜數,並將彈出的醜數分別乘以2,3,5後得到新的醜數並儲存到小根堆中(如果小根堆中沒有這個醜數),第n次彈出的醜數就是第n小的醜數。
時間複雜度和空間複雜度:動態規劃的時間複雜度為o(n),空間複雜度為o(1);而利用小根堆的解法的時間複雜度為o(nlogn),空間複雜度為o(n)。
實現**:
//解法1:動態規劃
public
intnthuglynumber
(int n)
return dp[n -1]
;}//解法2:利用小根堆
public
intnthuglynumber1
(int n)
;int count =0;
long res =1;
while
(!queue.
isempty()
&& count < n)
return
(int
)res;
}
劍指Offer 49 醜數
我們把只包含因子2 3和5的數稱為醜數。求按從小到大的順序的第1500個醜數。例 6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當作第乙個醜數。遍歷數字,對每個數字判斷是否只包含2 3 5因子。問題在於,有很多無用的計算,增加時間複雜度。時間複雜度 o n 空間複雜度 o 1 可以發現...
劍指offer49 醜數
把只包含質因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含質因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。思路 1.每次找出乙個最小丑數res i 都會產生三個新的醜數,2 res i 3 res i 5 res i 2.如果我...
劍指 Offer 49 醜數
我們把只包含質因子 2 3 和 5 的數稱作醜數 ugly number 求按從小到大的順序的第 n 個醜數。出看這道題可能感覺能算,但是思路就非常繁瑣。解法一 這個只說說思路,既然2,3,5是該數的因子,那麼該數除以2,3,5的餘數一定是 0 那麼就讓每個數連續除以2,3,5,只到餘數不為0 結果...