[前端]_一起刷leetcode 264. 丑数 II

150 阅读2分钟

大家好,我是挨打的阿木木,爱好算法的前端摸鱼老。最近会频繁给大家分享我刷算法题过程中的思路和心得。如果你也是想提高逼格的摸鱼老,欢迎关注我,一起学习。

题目

264. 丑数 II

给你一个整数 n ,请你找出并返回第 n 个 丑数 。

丑数 就是只包含质因数 23 和/或 5 的正整数。

 

示例 1:

输入: n = 10
输出: 12
解释: [1, 2, 3, 4, 5, 6, 8, 9, 10, 12] 是由前 10 个丑数组成的序列。

示例 2:

输入: n = 1
输出: 1
解释: 1 通常被视为丑数。

 

提示:

  • 1 <= n <= 1690

思路

这道题目太简洁了,我先给大家翻译一下题目的意思, 丑数指的是这个数只能由1乘以[2, 3, 5]中的任意一个元素,经过n轮乘法后达到的值。而且需要从小到大排列,我们可以直接用三根指针,指向我们当前的数组,然后分别标识当前指针乘到数组的第几位了,每次存放三根指针对应的最小值进数组即可。然后有个注意点,可能会有重复元素,比如2 * 3 = 3 * 2,这种情况两根指针都需要往后走一位。

举个例子:

p1 => 代表 * 2的指针, p2 => 代表 * 3的指针, p5 => 代表 * 5的指针

第一轮,数组中只有1

[ 1 ] => 三根指针都在索引为0的位置,这时候分别计算他们对应的值, 即 1 * 2, 1 * 3, 1 * 5 然后把最小值推进数组中,同时该指针往后移。

第二轮

[ 1, 2 ] => 第一根表示2的指针在索引1,后两根指针在索引为0的位置,这时候分别计算他们对应的值, 即 2 * 2, 1 * 3, 1 * 5 然后把最小值推进数组中,同时该指针往后移。

第三轮

[ 1, 2, 3 ] => 2 * 2, 2 * 3, 1 * 5

依此类推...

实现

/**
 * @param {number} n
 * @return {number}
 */
var nthUglyNumber = function(n) {
    let p1 = p2 = p3 = 0;

    let result = [ 1 ];

    while (result.length < n) {
        let v1 = result[p1] * 2,
            v2 = result[p2] * 3,
            v3 = result[p3] * 5;

        // 找它们的最小值,就是丑数
        let cur = Math.min(...[v1, v2, v3]);

        // 可能有重复值,所以不能用else if
        if (cur === v1) p1++;
        if (cur === v2) p2++;
        if (cur === v3) p3++;

        result.push(cur);
    }

    return result[n - 1];
};

看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。