美文网首页初见
力扣(LeetCode) - 313 超级丑数

力扣(LeetCode) - 313 超级丑数

作者: 小怪兽大作战 | 来源:发表于2019-11-02 11:39 被阅读0次

一、题目

编写一段程序来查找第 n 个超级丑数。

超级丑数是指其所有质因数都是长度为 k 的质数列表 primes 中的正整数。

示例:
输入: 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] 。

说明:
1 是任何给定 primes 的超级丑数。
给定 primes 中的数字以升序排列。
0 < k ≤ 100, 0 < n ≤ 106, 0 < primes[i] < 1000 。
第 n 个超级丑数确保在 32 位有符整数范围内。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/super-ugly-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、分析

这道题和《剑值offer》上的丑数那道题思路一样。
质数:是指在大于1的自然数中,除了1和它本身以外不再有其他因数
质因数:既是因数又是质数
题目要求出低n个超级丑数,如果从1开始遍历,求每个自然数的所有因数,然后在看其所有质因数是不是在质数列表 primes中,直到找到第n个超级丑数,这样的时间复杂度会非常高。
我们反向思维,从因数出发,只要从质数列表 primes中选取因数,那么乘积自然就是超级丑数。
用质数列表 primes中的数字不断与已经生成的超级丑数进行相乘,得到新的超级丑数。我们需要注意生成丑数的顺序。
用一个数组保存每个 primes中的质因数下一步应该和哪一个超级丑数相乘。

三、代码

    public int nthSuperUglyNumber(int n, int[] primes) {
        if (primes == null || primes.length == 0) {
            return 0;
        }
        int res[] = new int[n]; //保存的超级丑数
        int len = primes.length;
        int next[] = new int[len];  //primes中的每个质因数对应的下一个因数在res中的坐标
        int curSize = 1;
        res[0] = 1;
        while (curSize < n) { //计算n个超级丑数
            int nextNum = Integer.MAX_VALUE;
            for (int i = 0; i < primes.length; i++) { //计算一个超级丑数
                int temp = res[next[i]] * primes[i];
                if (temp < nextNum) {
                    nextNum = temp;
                }
            }
            res[curSize] = nextNum;
            for (int i = 0; i < len; i++) {  //更新因数坐标
                while (res[next[i]] * primes[i] <= res[curSize]) {
                    next[i]++;
                }
            }
            curSize++;
        }
        return res[n - 1];
    }

相关文章

网友评论

    本文标题:力扣(LeetCode) - 313 超级丑数

    本文链接:https://www.haomeiwen.com/subject/zfmcbctx.html