313:超级丑数
2022-04-04 本文已影响0人
nobigogle
题意
超级丑数是一个正整数,并满足其所有质因数都出现在质数数组 primes 中。
给你一个整数 n 和一个整数数组 primes ,返回第 n 个 超级丑数 。
题目数据保证第 n 个 超级丑数 在 32-bit 带符号整数范围内。
用例
1
输入:n = 12, primes = [2,7,13,19]
输出:32
解释:给定长度为 4 的质数数组 primes = [2,7,13,19],前 12 个超级丑数序列为:[1,2,4,7,8,13,14,16,19,26,28,32] 。
2
输入:n = 1, primes = [2,3,5]
输出:1
解释:1 不含质因数,因此它的所有质因数都在质数数组 primes = [2,3,5] 中。
误区
超级丑数包含的数不仅是质因数的整数倍,还会包含不同质因数之间的乘积。因此超级丑数一定是之前丑数乘以质因数得到的。
题解
使用优先队列
按照上述描述所示,首先将1压入队列,出队列的元素分别乘以质因数得到将来可能的超级丑数,因此就出现了重复数据【例如:2、7 在2出队列时候,会把14压进去,在7出队列的时候也把14压进去,因此需要去重操作】,根据题意重复数据需要去除。我们可以直接使用HashSet进行去重。
class Solution {
public int nthSuperUglyNumber(int n, int[] primes) {
PriorityQueue<Integer> q = new PriorityQueue<>();
// 初始化第一个超级丑数
q.add(1);
while (n-- > 0) {
int x = q.poll();
if (n == 0) return x;
for (int k : primes) {
// 按照题意-》数据保证第 n 个 超级丑数 在 32-bit 带符号整数范围内。
if (k <= Integer.MAX_VALUE / x) q.add(k * x);
// 暂时想不明白为什么这里需要根据取余去重
if (x % k == 0) break;
}
}
return -1; // never
}
}