丑数

面试题49. 丑数 【中等题】【动态规划】

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

输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。

题目讲解

【核心思想】

  • 动态规划

【思路】

  • 定义三个指针p2,p3,p5p2指向的数字永远乘2,p3指向的数字永远乘3,p5指向的数字永远乘5
  • 初始化所有指针都指向第一个丑数,即1
  • 我们从2*dp[p2], 3*dp[p3], 5*dp[p5]选取最小的一个数字,作为新的丑数。这边新的丑数就是2*dp[p2]=2*1=2,然后p2++
  • 此时p3和p5指向第1个丑数,p2指向第2个丑数。然后重复上一步
  • 这里基于的一个事实是,丑数数列是递增的,当p5指针在当前位置时,后面的数乘以5必然比前面的数乘以5大,所以下一个丑数必然是先考虑前面的数乘以5。p2,p3同理,所以才可以使用指针

【代码】

  public int nthUglyNumber(int n) {
    int p2=0,p3=0,p5=0;
    int[] dp=new int[n];
    dp[0]=1;
    for(int i=1;i<n;i++){
        dp[i]=Math.min(dp[p2]*2,Math.min(dp[p3]*3,dp[p5]*5));
        if(dp[i]==dp[p2]*2) p2++;
        if(dp[i]==dp[p3]*3) p3++;
        if(dp[i]==dp[p5]*5) p5++; 
    }
    return dp[n-1];
}

关注微信公众号“算法岗从零到无穷”,更多算法知识点告诉你。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值