[路飞]超级丑数

162 阅读1分钟

记录 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]
     }