LeetCode——313. 超级丑数(Java)

题目描述

题干:
超级丑数 是一个正整数,并满足其所有质因数都出现在质数数组 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] 中。

题解思路

返回第 n 个超级丑数,丑数是只包含质因子2,3和5的数称作丑数,第一个丑数为 1

这里的超级丑数还要求了除了 2,3,5 之外的质因数必须存在在primes数组中

这里我们必须知道一个规则,一个丑数和另外一个数相乘的结果还是丑数

于是我们可以根据这个规律依次得到满足条件的丑数,最后输出第 n 个

正确代码

    // 小根堆
    public int nthSuperUglyNumber(int n, int[] primes) {
        Set<Long> longHashSet = new HashSet<>();
        PriorityQueue<Long> heap = new PriorityQueue<>();
        // 首先放入第 1 个丑数
        longHashSet.add(1L);
        heap.offer(1L);
        int ugly = 0;
        // 依次得到顺序丑数并返回第 n 个
        for (int i = 0; i < n; i++) {
            long curr = heap.poll();
            ugly = (int) curr;
            for (int prime : primes) {
                long next = curr * prime;
                if (longHashSet.add(next)) {
                    heap.offer(next);
                }
            }
        }
        return ugly;
    }

总结

这里采用小根堆每次循环都额外增加了不用的计算消耗,如果采用动态规划的方法

声明一个数只保存下一个丑数这样会大大节省空间和后期维护的成本

如果文章存在问题或者有更好的题解,欢迎在评论区斧正和评论,各自努力,你我最高处见
posted @ 2021-08-09 09:33  21岁还不是架构师  阅读(108)  评论(0编辑  收藏  举报