Leetcode动态规划笔记3 丑数 II

丑数 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 通常被视为丑数。

动态规划解法:

丑数只包含质因数 2、3、5,每一个丑数由之前的丑数乘 2 或 3 或 5 得到,因此适用于动态规划解法,定义长度为 n 的 dp 数组存放所有丑数。例如,第 1 个丑数为 1,第 2 个丑数为 1 * 2,第 3 个丑数为 1 * 3,第 4 个丑数为 2 * 2, 第 5 个丑数为 1 * 5,以此类推。

要找到第 n 个丑数,难点在于需要从小到大找到第 n 个丑数。由上述方法,根据第 1 个丑数 1 乘质因子得到 2、3、5,根据第 2 个丑数 2 乘质因子得到 4、6、10,4 在 5 之前,涉及到丑数从小到大顺序的问题。

解决方法为:设定三个指针 p2,p3,p5(初始时均为 1),表示目前还没有乘过 2、3、5 的丑数位置。下一个丑数由三个指针所指向的丑数乘对应的 2 或 3 或 5 中的最小值,表示下一个丑数为之前的丑数乘 2、3、5 三个质因子之一所得到,且保证所有丑数从小到大排列的顺序。再判断下一个丑数具体为 dp[p2] * 2、 dp[p3] * 3、dp[p5] * 5 中的哪一个,将对应的指针 p ++,表示其位置的丑数已经乘过了相应的质因子,无需再乘。最终返回 dp 数组最后一个数,即为第 n 个丑数。

class Solution {
public:
    int nthUglyNumber(int n) {
        int p2 = 0, p3 = 0, p5 = 0;
        vector dp(n);
        dp[0] = 1; 
        for(int i = 1; i < n; i++){
            int num2 = dp[p2] * 2, num3 = dp[p3] * 3, num5 = dp[p5] * 5;
            dp[i] = min(min(num2, num3), num5);
            if(dp[i] == num2)   p2++;
            if(dp[i] == num3)   p3++;
            if(dp[i] == num5)   p5++;
        }
        return dp[n - 1];
    }
};

你可能感兴趣的:(Leetcode题目笔记,动态规划,leetcode,算法,c++)