264. 丑数 II

264. 丑数 II

原始题目链接:https://leetcode-cn.com/problems/ugly-number-ii/

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

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

示例 1:

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

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

解题思路:

动态规划,三步走,定义状态,dp[i]表示第i个丑数,初始化,第一个丑数是1,状态转移方程,后面的丑数都是由质因数2 3
5乘积得来的,因为要按照升序的顺序,所以每次取个最小值,同时也要去重,加条件判断(是否与当前丑数相等,再自增即可),具体实现看代码。

代码实现:

class Solution:
    def nthUglyNumber(self, n: int) -> int:
        # 定义状态dp[i]:表示第i个丑数
        # 初始化dp数组
        dp = [0] * (n + 1)
        # 第一个丑数是1,索引1为第一个丑数位置
        dp[1] = 1

        # 定义3个指针,p2 p3 p5
        # 因为后面的丑数是由当前的丑数乘以质因数2 3 5得来的
        # 所以使用3个指针分别指向还没有乘以2 3 5的数
        # p2 p3 p5初始化为第一个丑数1
        # 下一个丑数就是dp[p2] * 2, dp[p3] * 3, dp[p5] * 5当中的最小值
        # 如果dp[i]和 dp[p2] * 2, dp[p3] * 3, dp[p5] * 5某个相等,则
        # 第i个丑数就是该值,并且将px自增一个位置,用于下一次计算丑数
        # 并且要去重,例如2*5=10 5*2=10
        p2, p3, p5, = 1, 1, 1

        # 从第2个丑数位置开始找
        for i in range(2, n + 1):
            # 下一个可能的丑数
            n1, n2, n3 = dp[p2] * 2, dp[p3] * 3, dp[p5] * 5
            # 因为按升序,所以取最小
            dp[i] = min(n1, n2, n3)
            # 去重+自增位置,因为当前的丑数的乘法(乘2 3 或5)用过一次了
            if dp[i] == n1:
                p2 += 1
            if dp[i] == n2:
                p3 += 1
            if dp[i] == n3:
                p5 += 1
        
        # 第一个丑数的位置是1,返回第n个丑数
        return dp[n]

参考文献:
https://leetcode-cn.com/problems/ugly-number-ii/solution/chou-shu-ii-by-leetcode-solution-uoqd/

你可能感兴趣的:(#,动态规划,leetcode)