313. 超级丑数

难度 medium
超级丑数 是一个正整数,并满足其所有质因数都出现在质数数组 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 <= 106
1 <= primes.length <= 100
2 <= primes[i] <= 1000
题目数据 保证 primes[i] 是一个质数
primes 中的所有值都 互不相同 ,且按 递增顺序 排列

解题思路1:这道题目和264. 丑数 II是很相似的,可以用同样的方法解决。由于题目给定的质因数不再是2,3,5,而是一个数组,我们也可以用一个数组idx来记录每个质因数的最新idx[i],idx[i]表示第i个质因数在结果数组dp中的下标,该下标对应的丑数就是第i个质因数为了构建一个新的丑数使用的上一个丑数。当构建出当前丑数的时候,我们利用质因数数组找到构建出当前丑数的上一个丑数的下标,然后更新其下标。其实思路和264. 丑数 II是完全一样的。
代码 t77 s80 java

class Solution {
    public int nthSuperUglyNumber(int n, int[] primes) {
        int len = primes.length;
        int[] dp = new int[n];
        dp[0] = 1;
        int[] idx = new int[len];
        for(int i=1; i<n; i++){
            dp[i] = Integer.MAX_VALUE;
            for(int j=0; j<len; j++){
                // 找到当前最小的丑数
                dp[i] = Math.min(dp[i], dp[idx[j]] * primes[j]);
            }
            for(int j=0; j<len; j++){
                // 找到构建出当前丑数的上个丑数的下标,并加一
                // 表示那个丑数对应的情况已经涵盖了,需要往后考虑下一个丑数了
                if(dp[i]==dp[idx[j]]*primes[j]){
                    idx[j]++;
                }
            }
        }
        return dp[n-1];
    }
}

解题思路2:其实这道题目还可以用最小堆的方法解决,堆顶始终是目前构建的所有丑数中的最小值,每次取出当前的最小丑数,并且和质因数数组(也就是初始丑数数组)进行相乘,将得到的新的丑数入堆,直到出堆的丑数个数达到要求。这种方法其实就是无脑暴力方法,只要没达到个数要求,就一直构建丑数,然后利用最小堆的排序功能,每次都取出当前最小丑数,这样相当于就是按顺序排好了所有丑数,直到达到个数要求就返回,多的丑数就不管了。

代码 java t28 s5

class Solution {
    public int nthSuperUglyNumber(int n, int[] primes) {
        HashSet<Long> set = new HashSet<>();
        PriorityQueue<Long> q = new PriorityQueue<>();
        set.add(1L);
        q.add(1L);
        while(n-->0){
            long t = q.poll();
            if(n==0) return (int)t;
            for(int p : primes){
                if(!set.contains(t*p)){
                    set.add(t*p);
                    q.add(t*p);
                }
            }
        }
        return -1;
    }
}

参考资料
https://www.cnblogs.com/grandyang/p/5144918.html
https://leetcode-cn.com/problems/super-ugly-number/solution/gong-shui-san-xie-yi-ti-shuang-jie-you-x-jyow/

313. 超级丑数

上一篇:NPM 命令


下一篇:mica-mqtt 1.0.2 发布,完善 stater 和 example