三指针
因为只包含质因数2,3,5,所以结果肯定是这些因数的乘积。这里比较难的是怎们可以让乘积可以从小到大依次被计算。这里使用三指针, 分别指向2,3,5下次相乘的数值 所在结果数组中的位置。
- 初始化结果数组为
[1],开始都是与1相乘,即都从索引0开始,所以三指针数组初始化为[0, 0, 0] 2、3、5相乘之后得到乘积为2、3、5,其中2为最小值,将其推入结果中[1, 2],修改2对应的指针,指针数组为[1, 0, 0]- 继续相乘:
2、3、5与索引相对应值相乘之后得到乘积为4、3、5,3为最小值推入结果数组[1, 2, 3],3的指针+1,即[1, 1, 0] - 继续相乘结果为
4、6、5,其中4为最小值,加入结果[1, 2, 3, 4],同时修改2的指针,得到指针[2, 1, 0] - 继续相乘结果为
6、6、5,其中5为最小值,加入结果[1, 2, 3, 4, 5],同时修改5的指针,得到指针[2, 1, 1] - 继续相乘结果为
6、6、10,其中6为最小值,加入结果[1, 2, 3, 4, 5, 6],同时修改2和3的指针,得到[3, 2, 1] - 以此类推...
代码:
function nthUglyNumber(n: number): number {
const res: number[] = [1]
const rates = [0, 0, 0]
const set = new Set([1])
while(res.length !== n) {
let r2 = res[rates[0]] * 2
let r3 = res[rates[1]] * 3
let r5 = res[rates[2]] * 5
let min = Math.min(r2, r3, r5)
res.push(min)
if (min === r2) {
rates[0]++
}
if (min === r3) {
rates[1]++
}
if (min === r5) {
rates[2]++
}
}
return res[res.length - 1]
};