与动态规划的爱恨情仇——丑数Ⅱ

62 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情


最近一直在力扣刷题,也逐渐对各类题型有了自己的理解,所谓见招拆招,将自己的浅显经验分享一下,帮助更多在编程路上的朋友们。


丑数Ⅱ

给你一个整数 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

思路

质因数想必不会陌生,即使不知道是个啥概念,但是读出来就会发现这个词熟悉而又陌生,最近可太火了(纯路人,不懂什么是小黑子)

回到题目,质因数指的是指能整除给定正整数,不知道也不影响做题,题目也给出了指定的三个质因数:2,3,5。

我们要找到只能被2,3,5整除的第n个数,即第n个丑数。

因为丑数的因子只能是2,3,5的倍数,故我们需要变量存储第i个丑数使用了几个2,3,5,初始化factor为1,factor一定是递增的,以确保丑数是递增的。每次寻找第 i 个丑数时要取三个因子所得的最小值。定义dp[i]为第 i 个丑数,状态转移方程为dp[i] = Math.min(dp[factor2] * 2, Math.min(dp[factor3] * 3, dp[factor5] * 5)),如果用到了某个因子,就要将该因子的倍数加1。

题解

class Solution {
    public int nthUglyNumber(int n) {
        int factor2 = 1, factor3 = 1, factor5 = 1;
        int[] dp = new int[n + 1];
        dp[1] = 1;
        for(int i = 2; i <= n; i++) {
            dp[i] =  Math.min(dp[factor2] * 2, Math.min(dp[factor3] * 3, dp[factor5] * 5));
            if(dp[i] == dp[factor2] * 2) {
                factor2++;
            }
            if(dp[i] == dp[factor3] * 3) {
                factor3++;
            }
            if(dp[i] == dp[factor5] * 5) {
                factor5++;
            }
        }
        return dp[n];
    }
}