Leetcode刷题:剑指offer【面试题49 丑数】

【面试题49 丑数】

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

Leetcode题目对应位置: 面试题49:丑数

思路:动态规划。

丑数的递推性质:丑数 = 某个较小丑数 x 某因子(2/3/5)

因此在求解第 k 个丑数时,只需要求得前面的丑数中,分别乘2、乘3、乘5 后最小的一个即可。比如现在已知前 3 个丑数,求第 4 个丑数:

x1x2x3x4
123

用 3 个指针 a、b、c 分别用来代表乘2、乘3、乘5,初始时都指向 x1。

求 x2: x a ∗ 2 = 2 x_a * 2 = 2 xa2=2 x b ∗ 3 = 3 x_b * 3 = 3 xb3=3 x c ∗ 5 = 5 x_c * 5 = 5 xc5=5,最小的大于 x 1 x_1 x1 的值是 x a ∗ 2 = 2 x_a * 2 = 2 xa2=2,所以 x 2 = 2 x_2 = 2 x2=2,a 向后移动一个位置,指向 x2
求 x3: x a ∗ 2 = 4 x_a * 2 = 4 xa2=4 x b ∗ 3 = 3 x_b * 3 = 3 xb3=3 x c ∗ 5 = 5 x_c * 5 = 5 xc5=5,最小的大于 x 2 x_2 x2 的值是 x b ∗ 3 = 3 x_b * 3 = 3 xb3=3,所以 x 3 = 3 x_3 = 3 x3=3,b 向后移动一个位置,指向 x3
求 x3: x a ∗ 2 = 4 x_a * 2 = 4 xa2=4 x b ∗ 3 = 6 x_b * 3 = 6 xb3=6 x c ∗ 5 = 5 x_c * 5 = 5 xc5=5,最小的大于 x 3 x_3 x3 的值是 x a ∗ 2 = 4 x_a * 2 = 4 xa2=4,所以 x 4 = 4 x_4 = 4 x4=4,a 向后移动一个位置,指向 x4

在指针移动过程中,从 a、b、c 中选择一个乘积大于当前丑数的最小值,然后移动选中的指针,其余指针保持不变。

时间复杂度:O(n)
空间复杂度:O(n),创建额外的 dp 数组

class Solution:
    def nthUglyNumber(self, n: int) -> int:
        if n == 1: return 1
        a = b = c = 0
        dp = [1 for _ in range(n)]
        for i in range(1, n):
            t2, t3, t5 = dp[a]*2, dp[b]*3, dp[c]*5
            dp[i] = min(t2, t3, t5)
            if dp[i] == t2: a += 1
            if dp[i] == t3: b += 1
            if dp[i] == t5: c += 1
        return dp[-1]

参考代码:mian-shi-ti-49-chou-shu-dong-tai-gui-hua-qing-xi-t

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不吃饭就会放大招

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

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

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

打赏作者

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

抵扣说明:

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

余额充值