PAT A1019 General Palindromic Number (20) [回⽂數 進位制轉換]
阿新 • • 發佈:2020-07-18
劍指Offer_#49_醜數
劍指offerContents
題目
我們把只包含質因子 2、3 和 5 的數稱作醜數(Ugly Number)。求按從小到大的順序的第 n 個醜數。
示例:
輸入: n = 10
輸出: 12
解釋: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 個醜數。
說明:
- 1是醜數。
- n不超過1690。
思路分析
暴力迴圈
根據醜數的定義,我們可以判斷任何一個數字是否是醜數。所以可以從1開始,判斷每個正整數是否是醜數(不斷取餘,做除法),配合一個計數變數,就可以得到第n個醜數。
這種做法需要大量的取餘和除法運算。
遞推(通過已有的醜數找到新的醜數)
根據醜數的定義,每個醜數的只包含因子2,3,5,也就是說,醜數應該是另一個醜數乘以2、3、5的結果。通過這種方式,我們可以通過已有的醜數,找到新的醜數。
這種思路的關鍵在於如何保證得到的醜數序列是有序的?
假設我們已經得到了一個部分的醜數序列,為了獲取下一個醜數(必須是剛好比當前醜數大的第一個醜數),有兩個問題:
- 找哪個數字來乘以2/3/5?
- 乘2?還是乘3?還是乘5?
解決上述問題,採用三指標法:
三個指標初始化指向第一個醜數1,然後分別計算三個指標指向的數字乘2/3/5的結果,將其中最小的結果加入醜數序列,後移對應的指標。
解答
class Solution {
public int nthUglyNumber(int n) {
if(n == 0) return 0;
//*2,*3,*5三個陣列的指標
int a = 0,b = 0,c = 0;
int[] uglyNums = new int[n];
uglyNums[0] = 1;
for(int i = 1;i <= n - 1;i++){
int tmp = Math.min(2*uglyNums[a],Math.min(3*uglyNums[b],5 *uglyNums[c]));
if(tmp == 2 * uglyNums[a]) a++;
if(tmp == 3 * uglyNums[b]) b++;
if(tmp == 5 * uglyNums[c]) c++;
uglyNums[i] = tmp;
}
return uglyNums[n - 1];
}
}
複雜度分析
時間複雜度O(n)
空間複雜度O(n)