Leetcode刷题笔记——剑指 Offer 49. 丑数(中等)


题目描述

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

解题思路

丑数的递推性质: 丑数只包含因子 2 , 3 , 5 2, 3, 5 2,3,5 ,因此有 “丑数 = = = 某较小丑数 × \times × 某因子” (例如: 10 = 5 × 2 10 = 5 \times 2 10=5×2)。

设已知长度为 n n n 的丑数序列 x 1 , x 2 , ⋯   , x n x_1, x_2, \cdots , x_n x1,x2,,xn,求第 n + 1 n+1 n+1 个丑数 x n + 1 x_{n+1} xn+1 。根据递推性质,丑数 x n + 1 x_{n+1} xn+1 只可能是以下三种情况其中之一(索引 a , b , c a, b, c a,b,c 为未知数):
在这里插入图片描述
丑数递推公式: 若索引 a , b , c a,b,c a,b,c 满足以上条件,则下个丑数 x n + 1 x_{n+1} xn+1 为以下三种情况中的 最小值
x n + 1 = m i n ( x a × 2 , x b × 3 , x c × 5 ) x_n+1=min(x_a×2,x_b×3,x_c×5) xn+1=min(xa×2,xb×3,xc×5)
由于 x n + 1 x_{n+1} xn+1最接近 x n x_n xn 的丑数,因此索引 a , b , c a, b, c a,b,c 需满足以下条件:
在这里插入图片描述
在这里插入图片描述
因此,可设置指针 a , b , c a,b,c a,b,c 指向首个丑数(即 1 1 1 ),循环根据递推公式得到下个丑数,并每轮将对应指针执行 + 1 +1 +1 即可。
动态规划解析:

  • 状态定义: 设动态规划列表 d p dp dp d p [ i ] dp[i] dp[i] 代表第 i + 1 i + 1 i+1 个丑数;

  • 转移方程:
    1.当索引 a , b , c a, b, c a,b,c 满足以下条件时, d p [ i ] dp[i] dp[i] 为三种情况的最小值;
    2.每轮计算 d p [ i ] dp[i] dp[i] 后,需要更新索引 a , b , c a, b, c a,b,c 的值,使其始终满足方程条件。实现方法:
    分别独立判断 d p [ i ] dp[i] dp[i] d p [ a ] × 2 dp[a] \times 2 dp[a]×2 , d p [ b ] × 3 dp[b] \times 3 dp[b]×3 , d p [ c ] × 5 dp[c] \times 5 dp[c]×5 的大小关系,若相等则将对应索引 a a a , b b b , c c c 1 1 1
    在这里插入图片描述

  • 初始状态: d p [ 0 ] = 1 dp[0] = 1 dp[0]=1 ,即第一个丑数为 1 1 1

  • 返回值: d p [ n − 1 ] dp[n-1] dp[n1] ,即返回第 n n n 个丑数;

复杂度分析

  • 时间复杂度 O ( N ) O(N) O(N) : 其中 N = n N = n N=n ,动态规划需遍历计算 d p dp dp 列表。
  • 空间复杂度 O ( N ) O(N) O(N) : 长度为 N N N d p dp dp 列表使用 O ( N ) O(N) O(N) 的额外空间。

C++代码实现

class Solution {
public:
    int nthUglyNumber(int n) {
        int a = 0, b = 0, c = 0;
        int dp[n];
        dp[0] = 1;
        for(int i = 1; i < n; i++) {
            int n2 = dp[a] * 2, n3 = dp[b] * 3, n5 = dp[c] * 5;
            dp[i] = min(min(n2, n3), n5);
            if(dp[i] == n2) a++;
            if(dp[i] == n3) b++;
            if(dp[i] == n5) c++;
        }
        return dp[n - 1];
    }
};

参考链接

[1] https://leetcode-cn.com/problems/chou-shu-lcof/solution/mian-shi-ti-49-chou-shu-dong-tai-gui-hua-qing-xi-t/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

卑微小岳在线debug

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

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

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

打赏作者

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

抵扣说明:

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

余额充值