[路飞]_313. 超级丑数

95 阅读2分钟

这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」。
题目地址

题目描述

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

解题思路

方法一:动态规划

  • 定义一个数组ans,其中ans[i]表示第i个超级丑数,第n个超级丑数即为ans[n];
  • 由于最小的超级丑数是1,因此ans[1] = 1;
  • 创建于数组primes相同长度的数组pointers,表示下一个超级丑数是当前指针指向的超级丑数乘以对应的质因子。初始值,数组pointers的元素值都是1.
  • 开始循环整个n个超级丑数
  • 第一步:实现当前指针指向的超级丑数和对应的质因子的乘积,填入到nums临时数组内。
  • 然后取nums内的最小值
  • 第二步:循环nums内的值,如果nums[k]的值与当前ans[i]的值相等,就让指针往前移动一位。

丑数2.jpg

代码

var xx = function(n, primes){
    let ans = new Array(n + 1).fill(1);
    let pointers = new Array(primes.length).fill(1);
    let nums = [];
    for(let i = 2; i <= n; i++){
        // 第一步,获取当前指针指向的超级丑数和对应的质因子的值
        for(let j = 0; j < pointers.length; i++){
            nums[j] = ans[pointers[j]] * primes[j];
        }
        ans[i] = Math.min(...nums);
        // 指针移动
        for(let k = 0; k < nums.lenght; k++){
            if(ans[i] === nums[k]){
                pointers[k]++;
            }
        }
        nums = [];
    }
    return ans[k];
}