【LeetCode】264. 丑数 II(同剑指 Offer 49)

一、题目

编写一个程序,找出第 n 个丑数。

丑数就是质因数只包含 2, 3, 5 的正整数。

示例:

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

说明:

  1. 1 是丑数。
  2. n 不超过1690。

二、解决

1、优先级队列

思路:

丑数性质:丑数 = 某较小丑数 * 某因子

过程:从1开始,乘2、3、5后,取最小结果,再乘。循环至数量达到 n n n

代码:

class Solution {
    public int nthUglyNumber(int n) {
        if(n==1) return 1;
        PriorityQueue<Long> q = new PriorityQueue();
        q.add(1l);
        
        for(long i=1; i<n; i++) {
            long tmp = q.poll();
            while(!q.isEmpty() && q.peek()==tmp) tmp = q.poll();  // 去除重复的丑数
            q.add(tmp*2);
            q.add(tmp*3);
            q.add(tmp*5);
        }
        return q.poll().intValue();
    }
}

时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)

2、动态规划

思路:

1、状态定义
dp[i]:第i+1个丑数。

2、转移方程
dp[i+1] = min {dp[p2]*2, dp[p3]*3, dp[p5]*5}

3、初始值dp[0]=1,返回值dp[n-1]

代码:

class Solution {
    public int nthUglyNumber(int n) {
        int[] dp = new int[n+1]; // dp[i] holds the ith's ugly number
        dp[1] = 1;
        int p2 = 1, p3 = 1, p5 = 1;
        for (int i=2; i<=n; i++) { // loop invariant:dp[i] holds the smallest ith uglynumber
            dp[i] = Math.min(2*dp[p2], Math.min(3*dp[p3],5*dp[p5])); // the next ugly number must be built from a smaller ugly number
            if (dp[i] == 2*dp[p2]) p2++; 
            if (dp[i] == 3*dp[p3]) p3++;
            if (dp[i] == 5*dp[p5]) p5++;
        }
        return dp[n];
    }
}

时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)

三、参考

1、面试题49. 丑数(动态规划,清晰图解)
2、丑数 II
3、你绝对能轻松看得懂的丑数解题思路
4、Java solution – using PriorityQueue
5、Shortest O(n) Java DP solution

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值