1 题目
Write a program to find the nth
super ugly number.
Super ugly numbers are positive numbers whose all prime factors are in the given prime list primes
of size k
.
Example:
Input: n = 12, primes = [2,7,13,19]
Output: 32
Explanation: [1,2,4,7,8,13,14,16,19,26,28,32] is the sequence of the first 12
super ugly numbers given primes = [2,7,13,19] of size 4.
Note:
1
is a super ugly number for any givenprimes
.- The given numbers in
primes
are in ascending order. - 0 <
k
≤ 100, 0 <n
≤ 106, 0 <primes[i]
< 1000. - The nth super ugly number is guaranteed to fit in a 32-bit signed integer.
2 尝试解
2.1 分析
给定若干素数集,找出以这些素数(以及1)为因子的所有素数集排序后,其中的第n个元素。
以因子集Primes为[2,3,7]为例,初始素数集Ugly为[1],下一个添加的元应该是由素数集Ugly中所有的元素乘上因子集中的所有元素得到的结果集中,未添加过的最小的元素。如[1]→[1,2]→[1,2,3]→[1,2,3,4]→[1,2,3,4,6]。问题就变成了怎样产生下一个元素以及如何避免重复。
构造一个与Primes同样大小的索引集index,初始全为0,即全部指向Ugly[0]=1。然后取Ugly[index[i]]*Primes[i] for i in range(len(index))其中的最小值即为下一个要添加的元素。然后令所有能产生此结果的index++。
该问题与264 Ugly Number II问题相似。
2.2 代码
class Solution {
public:
int nthSuperUglyNumber(int n, vector<int>& primes) {
vector<int> saver{1};
vector<int> index(primes.size(),0);
while(saver.size() < n){
int min = INT_MAX;
for(int i = 0; i < index.size(); i++){
if(saver[index[i]]*primes[i] < min)
min = saver[index[i]]*primes[i];
}
saver.push_back(min);
for(int i = 0; i < index.size(); i++){
if(saver[index[i]]*primes[i] == min)
index[i]++;
}
}
return saver.back();
}
};
3 标准解
int nthSuperUglyNumber(int n, vector<int>& primes) {
vector<int> index(primes.size(), 0), ugly(n, INT_MAX);
ugly[0]=1;
for(int i=1; i<n; i++){
for(int j=0; j<primes.size(); j++) ugly[i]=min(ugly[i],ugly[index[j]]*primes[j]);
for(int j=0; j<primes.size(); j++) index[j]+=(ugly[i]==ugly[index[j]]*primes[j]);
}
return ugly[n-1];
}