难度:中等
题目:
超级丑数 是一个正整数,并满足其所有质因数都出现在质数数组 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 <= n <= 105
1 <= primes.length <= 100
2 <= primes[i] <= 1000
题目数据 保证 primes[i] 是一个质数
primes 中的所有值都 互不相同 ,且按 递增顺序 排列
Related Topics
数组
数学
动态规划
重点!!!解题思路
可先看前面讲过的LeetCode[264]丑数II,看看有没有灵感
再看看LeetCode[17.09]第k个数,都是相似题
第一步:
首先明确解题手段
我们之前的丑数题的质因子都是给定的,所以我们可以用堆来添加每轮的丑数
但是这道超级丑数题并没有给定质因子,我们并不知道一共几个质因子
所以我们这道题并不能使用堆来解决,只能用老办法数组来试试。
第二步:
我们也是在给定质因子中找出每轮的最小丑数
找到每轮的最小丑数之后,将它添加到集合中去,
添加到集合中去后进行下一轮判断,直到找到第n个位置为止。
讲解+源码:
class Solution {
public int nthSuperUglyNumber(int n, int[] primes) {
int[] p=new int[primes.length];//记录质因子出现的次数,出现一次就让p[i]++
List<Long> data=new ArrayList<>();//丑数序列集合
data.add(1L);//第一个丑数为1
long ans=1L;
while (data.size()!=n){
ans=primes[0]*data.get(p[0]);//拿到本轮的预计最小丑数
for (int i=1;i<primes.length;i++){//第一个质因子被用了,所以下标从1开始
ans=Math.min(ans,primes[i]* data.get(p[i]));//拿到本轮的丑数
}
for (int i=0;i<primes.length;i++){//这个循环增加每次循环丑数的下标,避免重复
if (primes[i]*data.get(p[i])==ans) p[i]++;
}
data.add(ans);//添加每轮出现的丑数
}
return (int) ans;
}
}
运行结果:
如果您还有什么疑问或解答有问题,可在下方评论,我会及时回复。
系列持续更新中,点个订阅吧