剑指 Offer 49. 丑数 (动态规划)

题目描述

我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。

思路分析

这道题实际上是leetcode主站的丑数2。

暴力会超时啊,我试过了哈哈,测试用例都直接超时了。

动规开始!

首先递推思想,某个丑数一定是由比他小的丑数 乘以2或3或5得到的。
且丑数需要从小到大排列,所以也就是说,当前丑数‘x‘乘以2或3或5 中的最小值就是下一个丑数。

//下一个最小的丑数一定在n2,n3,n5中。
			n2 = dp[a]*2
            n3 = dp[b]*3
            n5 = dp[c]*5

进而可得到递推公式:dp[i] = min(前一个丑数 * 2,前一个丑数 * 3 ,前一个丑数 * 5)

dp[i] = min(n2,n3,n5)

因此,可设置指针 a,b,c 指向首个丑数(即 1 ),循环根据递推公式得到下个丑数,并每轮将对应指针执行 +1 即可。

这块有一个细节需要注意,比如 2和3这俩分别由a和b指着,2 * 3 和3 * 2都是6。所以a和b指针都需要向后挪动。

//看看刚得到的最小丑数是n2还是n3还是n5。对应指针需要加1
			if dp[i] == n2:
                a+=1
            if dp[i] == n3:
                b+=1
            if dp[i] == n5:
                c+=1

这里设置三个指针的思想,可以想象成分别代表 * 2 * 3 * 5,当某个数被使用过了,则对应指针就往后挪动,表示已经考虑过该数的对应乘积了。

开始:
1.初始化dp含义:
dp[i]表示 第i+1个丑数

2.递推公式:
dp[i]=min(dp[a]×2,dp[b]×3,dp[c]×5)

3.初始化dp数组:
显然 dp[0] = 1

完整代码

class Solution:
    def nthUglyNumber(self, n: int) -> int:
        #dp[i] 表示 第i+1个丑数
        dp = [0] * n
        dp[0] = 1
        a =b=c = 0
        for i in range(1,n):
            n2 = dp[a]*2
            n3 = dp[b]*3
            n5 = dp[c]*5
            dp[i] = min(n2,n3,n5)
            if dp[i]==n2:
                a+=1
            if dp[i] == n3:
                b+=1
            if dp[i] == n5:
                c+=1
        return dp[-1]

        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深度不学习!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值