【动态规划】264. 丑数 II

题目:

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

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

示例:

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

1 是丑数。
n 不超过1690。

 

解答:

方法一:DP

 

 

class Solution {
    public int nthUglyNumber(int n) {
        int[] dp = new int[1691];
        dp[1] =1;
        int p2 = 1,p3 = 1,p5 = 1;
        for(int i = 2;i<=n;i++){
            int x = dp[p2]*2;
            int y = dp[p3]*3;
            int z = dp[p5]*5;
            dp[i] = Math.min(x,Math.min(y,z));

            //如果三个指针指向的下一个数有相同的,同时将指针+1,避免出现重复的丑数
            if(x == dp[i]){
                p2++;
            }
            if(y == dp[i]){
                p3++;
            }
            if(z == dp[i]){
                p5++;
            }
        }
        return dp[n];
    }
}

 

方法二:堆

 

 

注意整型变量溢出问题,这里使用了long类型。

最后的结果再变回int类型

class Ugly{
    int[] nums = new int[1690];
    Ugly(){
        PriorityQueue<Long> heap = new PriorityQueue<>();
        Set<Long> set = new HashSet<>();

        set.add(1L);
        heap.add(1L);

        int[] p = new int[]{2,3,5};
        for(int i =0;i<1690;i++){
            long num = heap.poll();
            nums[i] = (int)num;
            for(int k:p){
                if(!set.contains(num*k)){
                    heap.add(num*k);
                    set.add(num*k);
                }
            }
        }
    }
}


class Solution {
    //使用静态类对象,每个类只有一个。Ugly的构造函数只运行一次。结果存储在nums[]数组中,对于除了第一个测试用例以外的用例只需查表就行
    public static Ugly ugly = new Ugly();
    public int nthUglyNumber(int n) {
        return ugly.nums[n-1];
    }
}

 

posted @ 2020-09-26 21:58  3KBLACK  阅读(94)  评论(0)    收藏  举报