1. 程式人生 > 實用技巧 >PAT A1019 General Palindromic Number (20) [回⽂數 進位制轉換]

PAT A1019 General Palindromic Number (20) [回⽂數 進位制轉換]

劍指Offer_#49_醜數

劍指offer

Contents

題目

我們把只包含質因子 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)