313. Super Ugly Number
Description
A super ugly number is a positive integer whose prime factors are in the array primes.
Given an integer n and an array of integers primes, return the nth super ugly number.
The nth super ugly number is guaranteed to fit in a 32-bit signed integer.
Example 1:
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].
Example 2:
Input: n = 1, primes = [2,3,5] Output: 1 Explanation: 1 has no prime factors, therefore all of its prime factors are in the array primes = [2,3,5].
Constraints:
1 <= n <= 1051 <= primes.length <= 1002 <= primes[i] <= 1000primes[i]is guaranteed to be a prime number.- All the values of
primesare unique and sorted in ascending order.
Solutions
Solution 1: Priority Queue (Min Heap)
Thinking
A super ugly number uses only the given primes. Trial-dividing every integer is too slow for large \(n\).
Start from \(1\), pop the heap minimum \(x\), and push \(x\times p\) when it does not overflow. If \(x\) is divisible by the current prime, skip later primes (Euler-sieve style). The \(n\)-th pop is the answer.
We use a priority queue (min heap) to maintain all possible super ugly numbers, initially putting \(1\) into the queue.
Each time we take the smallest super ugly number \(x\) from the queue, multiply \(x\) by each number in the array primes, and put the product into the queue. Repeat the above operation \(n\) times to get the \(n\)th super ugly number.
Since the problem guarantees that the \(n\)th super ugly number is within the range of a 32-bit signed integer, before we put the product into the queue, we can first check whether the product exceeds \(2^{31} - 1\). If it does, there is no need to put the product into the queue. In addition, the Euler sieve can be used for optimization.
The time complexity is \(O(n \times m \times \log (n \times m))\), and the space complexity is \(O(n \times m)\). Where \(m\) and \(n\) are the length of the array primes and the given integer \(n\) respectively.
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
Solution 2: Dynamic Programming + Multi-pointer Heap
Thinking
Method 1 fans each ugly number across every prime and the heap grows large. Keep one pointer per prime: the heap top is the next candidate; after writing it, push that prime's next multiple. The heap stays \(O(m)\) and the time is \(O(n\log m)\).
Store the first \(n\) super ugly numbers in \(ugly[1..n]\), and keep a min-heap. Each heap entry belongs to one prime \(p\) and records the next candidate \(p \times ugly[\textit{index}]\).
Initialize \(ugly[1] = 1\) and push \((p, p, 2)\) for every prime. Repeatedly pop the heap minimum into \(ugly\), then advance that prime's pointer and push it back. Each prime keeps a single pointer, so we do not expand every generated ugly number against the whole prime list.
The time complexity is \(O(n \times \log m)\), and the space complexity is \(O(n + m)\), where \(m\) is the length of \(\textit{primes}\).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | |