[路飞]_leetcode_264. 丑数 II

343 阅读3分钟

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

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

解题思路

这一题可以利用动态规划,定义一个数组dp[], dp[i-1],表示第i个丑数,由于最小丑数为1,所以dp[0] = 1。

设三个指针分别指向dp[0]位置 p2 = 0, p3 = 0, p5 = 0,利用3指针获取他们不同的合数,每个指针都取所对应数组中的质因数让它与 2,3,5 相乘取最小合数作为下一个位置的值,当遇到合数的质因数为2,3,5三个指针时,质因数的指针位数+1

示例1 n = 10

     1
    [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
    p2
    p3
    p5
    // dp[1]的合数为235,取最小数2,因为2是合数的质因数,所以p2往前移一位
     1   2
    [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
        p2
    p3
    p5

    2 * dp[p2] = 4
    3 * dp[p3] = 3
    5 * dp[p5] = 5
    // dp[2]的合数为435,取最小数3,因为3是合数的质因数,所以p3往前移一位
     1   2   3
    [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
        p2
        p3
    p5

    2 * dp[p2] = 4
    3 * dp[p3] = 6
    5 * dp[p5] = 5
    // dp[2]的合数为465,取最小数4,因为2是合数的质因数,所以p2往前移一位
     1   2   3   4
    [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
            p2
        p3
    p5

    2 * dp[p2] = 6
    3 * dp[p3] = 6
    5 * dp[p5] = 5
    // dp[2]的合数为665,取最小数5,因为5是合数的质因数,所以p5往前移一位
     1   2   3   4   5
    [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
            p2
        p3
        p5

    2 * dp[p2] = 6
    3 * dp[p3] = 6
    5 * dp[p5] = 10
    // dp[2]的合数为6610,取最小数5,因为2, 3是合数的质因数,所以p2,p3往前移一位
     1   2   3   4   5   6
    [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
                p2
            p3
        p5

    2 * dp[p2] = 8
    3 * dp[p3] = 9
    5 * dp[p5] = 10
    // dp[2]的合数为8910,取最小数8,因为2是合数的质因数,所以p2往前移一位
     1   2   3   4   5   6   8
    [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
                    p2
            p3
        p5

    2 * dp[p2] = 10
    3 * dp[p3] = 9
    5 * dp[p5] = 10
    // dp[2]的合数为10910,取最小数9,因为3是合数的质因数,所以p3往前移一位
     1   2   3   4   5   6   8   9
    [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
                    p2
                p3
        p5

    2 * dp[p2] = 10
    3 * dp[p3] = 12
    5 * dp[p5] = 10
    // dp[2]的合数为101210,取最小数10,因为2,5是合数的质因数,所以p2,p5往前移一位
     1   2   3   4   5   6   8   9   10
    [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
                        p2
                p3
            p5

    2 * dp[p2] = 12
    3 * dp[p3] = 12
    5 * dp[p5] = 15
    // dp[2]的合数为121215,取最小数12,因为2,3是合数的质因数,所以p2,p3往前移一位
     1   2   3   4   5   6   8   9   10 12
    [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
                            p2
                    p3
            p5

    最后得到第10个整数为12

代码

var nthUglyNumber = function(n) {
    var dp = new Array();
    dp[0] = 1;
    var p2 = 0,
        p3 = 0,
        p5 = 0;
    for (let i = 1; i < n; i++) {
        dp[i] = Math.min(dp[p2] * 2, Math.min(dp[p3] * 3, dp[p5] * 5));

        if (dp[i] === dp[p2] * 2) p2++;
        if (dp[i] === dp[p3] * 3) p3++;
        if (dp[i] === dp[p5] * 5) p5++;
    }
    return dp[n-1];
};