1. 程式人生 > >[Leetcode] 第313題 超級醜數

[Leetcode] 第313題 超級醜數

 

一、題目描述

編寫一段程式來查詢第 n 個超級醜數。

超級醜數是指其所有質因數都是長度為 k 的質數列表 primes 中的正整數。

示例:

輸入: n = 12, primes = [2,7,13,19]
輸出: 32 
解釋: 給定長度為 4 的質數列表 primes = [2,7,13,19],前 12 個超級醜數序列為:[1,2,4,7,8,13,14,16,19,26,28,32] 。

說明:

  • 1 是任何給定 primes 的超級醜數。
  •  給定 primes
     中的數字以升序排列。
  • 0 < k ≤ 100, 0 < n ≤ 106, 0 < primes[i] < 1000 。
  • 第 n 個超級醜數確保在 32 位有符整數範圍內。

二、題目分析

1)參考醜數II中用的方法,不同的是醜數II中只有2,3,5三個質因數,而現在的質因數個數不一定
2)醜數II中使用pos2,pos3,pos5分別代表當前應該乘以2,3,5的位置,那麼現在用idx[i]來代表當前應該乘以primes[i]的位置
3)同樣的,dp[i]代表第i-1個醜數
4)那麼dp[i]=min{dp[idx[j]]*primes[j]},0<=j<idx.size(),也就是選擇當前位置的醜數和應該乘以的質因數的最小值
5)注意重合的情況,也就是說不一定只有一個位置產生最小值

,所有產生最小值的位置都要向後移動

 

三、程式碼實現

 1 class Solution {
 2 public:
 3     int nthSuperUglyNumber(int n, vector<int>& primes) {
 4         if (n < 1)return 0;
 5         vector<int> dp(n, 0);
 6         int m = primes.size();
 7         if (!m)return 1;
 8         vector<int> idx(m, 0
); 9 dp[0] = 1; 10 int min_pos; 11 for (int i = 1; i < n; ++i) { 12 dp[i] = dp[idx[0]] * primes[0]; 13 min_pos = 0; 14 for (int j = 1; j < m; ++j) { 15 if (dp[i] > dp[idx[j]] * primes[j]) { 16 dp[i] = dp[idx[j]] * primes[j]; 17 } 18 } 19 for (int j = 0; j < m; ++j) { 20 if (dp[i] == dp[idx[j]] * primes[j])//有的會有重合的部分,比如2*7==7*2,所有的位置都要向後移動 21 ++idx[j]; 22 } 23 } 24 return dp[n - 1]; 25 } 26 };