记录 1 道算法题
超级丑数
313. 超级丑数 - 力扣(LeetCode) (leetcode-cn.com)
关于丑数可以先看上面的文章。
超级丑数和丑数的区别就在于,丑数指定了是 2, 3, 5 之一的倍数。而超级丑数是传入一个数组,满足数组里面的某个数的倍数。超级丑数是没有固定质数的数量,他可能有3个,也可能有5个,而且值也是不固定的。
所以我们要用一个数组来存指针,和传入的质数数组一一对应。
由于不能写死,所以就要动态的计算最小值,同时也要考虑如何匹配哪个指针往前走。
function nthSuperUglyNumber(n, primes) {
// 生成结果数组
const arr = new Array(n + 1)
// 第一位默认是 1
arr[1] = 1
// 存放指针,一开始都指向 结果数组下标 1
const point = new Array(primes.length).fill(1)
let k = []
for (let i = 2; i <= n; i++) {
// 利用了reduce 计算最小值,
// 计算的同时还将最小值的下标存放到数组里面,
// 最后将需要前进的下标遍历一遍自增 1 就可以了。
arr[i] = primes.reduce((a, b, index) => {
// 倍数 * 指针指着的数 推导后面的丑数
b = b * arr[point[index]]
if (a < b) return a
// 当新的数更小的时候,清空最小值的指针下标
if (a > b) k.length = 0
// 推入最小值的指针下标
k.push(index)
return b
}, Infinity)
// 更新指针
k.forEach(j => {
point[j]++
})
}
return arr[n]
}