原题网址:https://leetcode.com/problems/super-ugly-number/
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
. For example, [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) 1
is a super ugly number for any given primes
.
(2) The given numbers in primes
are in ascending order.
(3) 0 < k
≤ 100, 0 < n
≤ 106, 0 < primes[i]
< 1000.
使用最小堆的最直接的思路,但无法通过时限要求:
public class Solution {
public int nthSuperUglyNumber(int n, int[] primes) {
PriorityQueue<Long> heap = new PriorityQueue<>();
for(int prime : primes) heap.offer((long)prime);
long ugly = 1;
for(int i = 1; i < n; i++) {
long prev = ugly;
ugly = heap.poll();
while (ugly == prev) ugly = heap.poll();
for(int prime : primes) heap.offer(ugly * prime);
}
return (int)ugly;
}
}
方法:动态规划+最小堆。
public class Solution {
public int nthSuperUglyNumber(int n, int[] primes) {
if (n<=1) return 1;
int[] nums = new int[n];
nums[0] = 1;
int[] pos = new int[primes.length];
PriorityQueue<Integer> minHeap = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer i1, Integer i2) {
return Integer.compare(nums[pos[i1]] * primes[i1], nums[pos[i2]] * primes[i2]);
}
});
for(int i=0; i<primes.length; i++) minHeap.add(i);
for(int i=1; i<n; i++) {
do {
int min = minHeap.poll();
nums[i] = nums[pos[min]] * primes[min];
pos[min] ++;
minHeap.offer(min);
} while (nums[i]==nums[i-1]);
}
return nums[n-1];
}
}