leetcode每日刷题: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

题解:利用动态规划

定义数组 dp,其中 dp[i]表示第 i 个丑数,

第 n 个丑数即为dp[n]。

由于最小的丑数是 1,因此 dp[1]=1

如何得到其余的丑数呢?

定义三个指针 p2,p3,p5,表示下一个丑数是当前指针指向的丑数乘以对应的质因数。

初始时,三个指针的值都是 1。

当 2≤i≤n时,令 dp[i]=min⁡(dp[p2]×2,dp[p3]×3,dp[p5]×5),

然后分别比较 dp[i] 和 dp[p2],dp[p3],dp[p5]是否相等,如果相等则将对应的指针加 1。

 

 

一开始,丑数只有{1},1可以同2,3,5相乘,取最小的1×2=2添加到丑数序列中。

现在丑数中有{1,2},在上一步中,1已经同2相乘过了,所以今后没必要再比较1×2了,我们说1失去了同2相乘的资格。

现在1有与3,5相乘的资格,2有与2,3,5相乘的资格,但是2×3和2×5是没必要比较的,因为有比它更小的1可以同3,5相乘,所以我们只需要比较1×3,1×5,2×2。

依此类推,每次我们都分别比较有资格同2,3,5相乘的最小丑数,选择最小的那个作为下一个丑数

假设选择到的这个丑数是同i(i=2,3,5)相乘得到的,所以它失去了同i相乘的资格,把对应的pi++,让pi指向下一个丑数即可。

class Solution:
    def nthUglyNumber(self, n: int) -> int:
        dp = [0]*(n+1)
        dp[1]=1
        p2=p3=p5=1
        for i in range(2,n+1):
            num2,num3,num5 = dp[p2]*2,dp[p3]*3,dp[p5]*5
            dp[i] = min(num2,num3,num5)
            if dp[i]==num2:
                p2+=1
            if dp[i] == num3:
                p3+=1
            if dp[i] == num5:
                p5+=1
        return dp[n]

 

 

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