# Super Ugly Number (Number whose prime factors are in given set)

Super ugly numbers are positive numbers whose all prime factors are in the given prime list. Given a number n, the task is to find n’th Super Ugly number.

It may be assumed that given set of primes is sorted. Also, first Super Ugly number is 1 by convention.

Examples:

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

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

In our previous post we discussed about Ugly Number. This problem is basically extension of Ugly Numbers.

A simple solution for this problem is to one by one pick each number starting from 1 and find its all primes factors, if all prime factors lie in the given set of primes that means number is Super Ugly. Repeat this process until we get n’th Super Ugly Number .

An efficient solution for this problem is similar to Method-2 of Ugly Number. Here is the algorithm :

1. Let k be size of given array of prime numbers.
2. Declare a set for super ugly numbers.
3. Insert first ugly number (which is always 1) into set.
4. Initialize array multiple_of[k] of size k with 0. Each element of this array is iterator for corresponding prime in primes[k] array.
5. Initialize nextMultipe[k] array with primes[k]. This array behaves like next multiple variables of each prime in given primes[k] array i.e; nextMultiple[i] = primes[i] * ugly[++multiple_of[i]].
6. Now loop until there are n elements in set ugly.
a). Find minimum among current multiples of primes in nextMultiple[] array and insert it in the set of ugly numbers.
b). Then find this current minimum is multiple of which prime .
c). Increase iterator by 1 i.e; ++multiple_Of[i], for next multiple of current selected prime and update nextMultiple for it.

Below is implementation of above steps.

 // 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; }

Output:

8

This article is contributed by Shashank Mishra ( Gullu ). If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Another method (using priority_queue)
Here we use min heap priority_queue.
The idea is to push the first ugly no. which is 1 into priority_queue and at every iteration take the top of priority_queue and push all the mulitples of that top into priotiy_queue.
Assuming a[] = {2, 3, 5},
so at first iteration 1 is top so 1 is popped and 1 * 2, 1 * 3, 1 * 5 is pushed.
At second iteration min is 2, so it is popped and 2 * 2, 2 * 3, 2 * 5 is pushed and so on.

 // 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, 1000)<

Output:

51200000

Time Complexity: O(nlogn)
Auxiliary Space: O(n)

GeeksforGeeks has prepared a complete interview preparation course with premium videos, theory, practice problems, TA support and many more features. Please refer Placement 100 for details

My Personal Notes arrow_drop_up

Improved By : prajmsidc