超级丑数是所有质因数都在给定质数列表中的正数。给定一个数 n,任务是找到第 n 个超级丑数。
可以假设给定的一组素数已排序。此外,按照惯例,第一个超级丑陋的数字是 1。
例子:
Input : primes[] = [2, 5]
n = 5
Output : 8
Super Ugly numbers with given prime factors
are 1, 2, 4, 5, 8, ...
Fifth Super Ugly number is 8
Input : primes[] = [2, 3, 5]
n = 50
Output : 243
Input : primes[] = [3, 5, 7, 11, 13]
n = 9
Output: 21
在我们之前的帖子中,我们讨论了丑数。这个问题基本上是Ugly Numbers的扩展。
这个问题的一个简单解决方案是从1开始一个一个地挑选每个数字并找到它的所有素数因子,如果所有素数因子都在给定的素数集合中,则意味着该数字是超级丑陋的。重复这个过程,直到我们得到第 n 个超级丑数。
此问题的有效解决方案类似于丑数的方法 2。这是算法:
- 令k为给定素数数组的大小。
- 为超级丑陋的数字声明一个集合。
- 将第一个难看的数字(始终为 1)插入集合中。
- 用 0 初始化大小为 k 的数组 multiple_of[k] 。该数组的每个元素都是 primes[k] 数组中相应素数的迭代器。
- 用素数[k] 初始化nextMultipe[k] 数组。这个数组的行为类似于给定素数[k]数组中每个素数的下一个多个变量,即; nextMultiple[i] = primes[i] * 丑陋的[++multiple_of[i]]。
- 现在循环,直到集合中有 n 个元素丑陋。
一种)。在 nextMultiple[] 数组中找到当前素数倍数中的最小值并将其插入到丑数集合中。
b)。然后找到这个当前最小值是哪个素数的倍数。
C)。将迭代器增加 1,即; ++multiple_Of[i],用于当前选定素数的下一个倍数并为其更新 nextMultiple。
下面是上述步骤的实现。
CPP
// C++ program to find n'th Super Ugly number
#include
using namespace std;
// Function to get the nth super ugly number
// primes[] --> given list of primes f size k
// ugly --> set which holds all super ugly
// numbers from 1 to n
// k --> Size of prime[]
int superUgly(int n, int primes[], int k)
{
// nextMultiple holds multiples of given primes
vector nextMultiple(primes, primes+k);
// To store iterators of all primes
int multiple_Of[k];
memset(multiple_Of, 0, sizeof(multiple_Of));
// Create a set to store super ugly numbers and
// store first Super ugly number
set ugly;
ugly.insert(1);
// loop until there are total n Super ugly numbers
// in set
while (ugly.size() != n)
{
// Find minimum element among all current
// multiples of given prime
int next_ugly_no = *min_element(nextMultiple.begin(),
nextMultiple.end());
// insert this super ugly number in set
ugly.insert(next_ugly_no);
// loop to find current minimum is multiple
// of which prime
for (int j=0; j dp[++index[j]]
set::iterator it = ugly.begin();
for (int i=1; i<=multiple_Of[j]; i++)
it++;
nextMultiple[j] = primes[j] * (*it);
break;
}
}
}
// n'th super ugly number
set::iterator it = ugly.end();
it--;
return *it;
}
/* Driver program to test above functions */
int main()
{
int primes[] = {2, 5};
int k = sizeof(primes)/sizeof(primes[0]);
int n = 5;
cout << superUgly(n, primes, k);
return 0;
}
CPP
// C++ program for super ugly number
#include
using namespace std;
//function will return the nth super ugly number
int ugly(int a[], int size, int n){
//n cannot be negative hence return -1 if n is 0 or -ve
if(n <= 0)
return -1;
if(n == 1)
return 1;
// Declare a min heap priority queue
priority_queue, greater> pq;
// Push all the array elements to priority queue
for(int i = 0; i < size; i++){
pq.push(a[i]);
}
// once count = n we return no
int count = 1, no;
while(count < n){
// Get the minimum value from priority_queue
no = pq.top();
pq.pop();
// If top of pq is no then don't increment count. This to avoid duplicate counting of same no.
if(no != pq.top())
{
count++;
//Push all the multiples of no. to priority_queue
for(int i = 0; i < size; i++){
pq.push(no * a[i]);
// cnt+=1;
}
}
}
// Return nth super ugly number
return no;
}
/* Driver program to test above functions */
int main(){
int a[3] = {2, 3,5};
int size = sizeof(a) / sizeof(a[0]);
cout << ugly(a, size, 10)<
Python3
# Python3 program for super ugly number
# function will return the nth super ugly number
def ugly(a, size, n):
# n cannot be negative hence return -1 if n is 0 or -ve
if(n <= 0):
return -1
if(n == 1):
return 1
# Declare a min heap priority queue
pq = []
# Push all the array elements to priority queue
for i in range(size):
pq.append(a[i])
# once count = n we return no
count = 1
no = 0
pq = sorted(pq)
while(count < n):
# sorted(pq)
# Get the minimum value from priority_queue
no = pq[0]
del pq[0]
# If top of pq is no then don't increment count.
# This to avoid duplicate counting of same no.
if(no != pq[0]):
count += 1
# Push all the multiples of no. to priority_queue
for i in range(size):
pq.append(no * a[i])
# cnt+=1
pq = sorted(pq)
# Return nth super ugly number
return no
# /* Driver program to test above functions */
if __name__ == '__main__':
a = [2, 3,5]
size = len(a)
print(ugly(a, size, 1000))
# This code is contributed by mohit kumar 29.
Javascript
输出:
8
另一种方法(使用priority_queue)
这里我们使用最小堆priority_queue。
这个想法是推第一个丑陋的不。它是 1 到 priority_queue 中,并且在每次迭代时取priority_queue 的顶部并将该顶部的所有倍数推入priority_queue。
假设 a[] = {2, 3, 5},
所以在第一次迭代 1 是顶部,所以 1 被弹出并且 1 * 2, 1 * 3, 1 * 5 被推送。
在第二次迭代时 min 为 2,因此它被弹出并推送 2 * 2、2 * 3、2 * 5 等等。
CPP
// C++ program for super ugly number
#include
using namespace std;
//function will return the nth super ugly number
int ugly(int a[], int size, int n){
//n cannot be negative hence return -1 if n is 0 or -ve
if(n <= 0)
return -1;
if(n == 1)
return 1;
// Declare a min heap priority queue
priority_queue, greater> pq;
// Push all the array elements to priority queue
for(int i = 0; i < size; i++){
pq.push(a[i]);
}
// once count = n we return no
int count = 1, no;
while(count < n){
// Get the minimum value from priority_queue
no = pq.top();
pq.pop();
// If top of pq is no then don't increment count. This to avoid duplicate counting of same no.
if(no != pq.top())
{
count++;
//Push all the multiples of no. to priority_queue
for(int i = 0; i < size; i++){
pq.push(no * a[i]);
// cnt+=1;
}
}
}
// Return nth super ugly number
return no;
}
/* Driver program to test above functions */
int main(){
int a[3] = {2, 3,5};
int size = sizeof(a) / sizeof(a[0]);
cout << ugly(a, size, 10)<
蟒蛇3
# Python3 program for super ugly number
# function will return the nth super ugly number
def ugly(a, size, n):
# n cannot be negative hence return -1 if n is 0 or -ve
if(n <= 0):
return -1
if(n == 1):
return 1
# Declare a min heap priority queue
pq = []
# Push all the array elements to priority queue
for i in range(size):
pq.append(a[i])
# once count = n we return no
count = 1
no = 0
pq = sorted(pq)
while(count < n):
# sorted(pq)
# Get the minimum value from priority_queue
no = pq[0]
del pq[0]
# If top of pq is no then don't increment count.
# This to avoid duplicate counting of same no.
if(no != pq[0]):
count += 1
# Push all the multiples of no. to priority_queue
for i in range(size):
pq.append(no * a[i])
# cnt+=1
pq = sorted(pq)
# Return nth super ugly number
return no
# /* Driver program to test above functions */
if __name__ == '__main__':
a = [2, 3,5]
size = len(a)
print(ugly(a, size, 1000))
# This code is contributed by mohit kumar 29.
Javascript
输出:
51200000
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。