题目描述
超级丑数 是一个正整数,并满足其所有质因数都出现在质数数组 primes 中。
给你一个整数 n 和一个整数数组 primes ,返回第 n 个 超级丑数 。
题目数据保证第 n 个 超级丑数 在 32-bit 带符号整数范围内。
解题思路
算法
动态规划,dp[i] 是第 i 个丑数
过程
对于每一个丑数,都是由另一个丑数(从 1 开始)乘上给的因子得来的(prime[i]),因此我们要做的,就是从小到大把丑数列出来放到 dp,然后返回 dp[n - 1] 即可
在计算过程中,我们用一个数组,作为每个与因数相乘的丑数的 index,因为每个丑数都只和因数有一个相乘机会。 在用一个数组来存放已经计算好的丑数
另外在计算过程中,我们要注意的一点是,在得到一个丑数的时候,如果发现已经计算过的丑数值里,已经有了相同的丑数(这个丑数肯定还没放入 dp),那么我们要将所有相等于本轮最小值丑数的因子,他对应的 index 进行 ++ 操作,然后再算出一个新的丑数出来,这是我们去重的关键
代码
/**
* @param {number} n
* @param {number[]} primes
* @return {number}
*/
var nthSuperUglyNumber = function (n, primes) {
const dp = new Array(n + 1).fill(0)
const m = primes.length
const pointers = new Array(m).fill(0)
const nums = new Array(m).fill(1)
for (let i = 1; i <= n; i++) {
let minNum = Number.MAX_SAFE_INTEGER
for (let j = 0; j < m; j++) {
minNum = Math.min(minNum, nums[j])
}
dp[i] = minNum
for (let j = 0; j < m; j++) {
if (nums[j] == minNum) {
pointers[j]++
nums[j] = dp[pointers[j]] * primes[j]
}
}
}
return dp[n]
}