Leetcode313:超級醜數
阿新 • • 發佈:2018-12-05
編寫一段程式來查詢第 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] 。
解題思路:
多指標法。
- 假設素數的個數是nums,那麼就分配nums個指標,它們的屬性是primes[i],使得每個指標對應它們指向第k個素數。初始時刻所有指標都指向1,第0個素數。
- 下一個醜數必然是這nums個指標指向的數分別乘以它們的屬性,然後在nums個數字中取最小值min。
- 這些指標中,所有計算結果等於min的都必須向後移動一個單位,否則下一次計算就會小於當前得到的醜數。
- 由此可見等待計算的數字不可能超過nums個,因此複雜度為O(n*nums)。
class Solution { public: int nthSuperUglyNumber(int n, vector<int>& primes) { int size = primes.size(), i, j; vector<int> sgn(size, 0); vector<int> ret(1, 1); for (i = 1; i < n; i++) { int minVal = INT_MAX; vector<int> move; for (j = 1; j <= size; j++) { int newdata = ret[sgn[j - 1]] * primes[j - 1]; if (newdata == minVal) move.push_back(j); else if(newdata<minVal){ move.clear(); move.push_back(j); } minVal = min(minVal, ret[sgn[j - 1]] * primes[j - 1]); } ret.push_back(minVal); for (j = 1; j <= int(move.size()); j++) { sgn[move[j - 1] - 1]++; } } return ret.back(); } }; |
class Solution { public: int nthSuperUglyNumber(int n, vector<int>& primes) { if (n == 1) return 1; int l = primes.size(); vector<int> ugly(n,INT_MAX); vector<int> tmp(l,1); vector<int> count(l,0); int next = 1; for (int i = 0; i < n; i++) { ugly[i] = next; next = INT_MAX; for (int j = 0; j < l; j++) { if (tmp[j] == ugly[i]) { tmp[j] = ugly[count[j]]*primes[j]; count[j]++; } next = min(next,tmp[j]); } } return ugly[n-1]; } }; |