丑数 II

264. 丑数 II
给你一个整数 n ,请你找出并返回第 n 个 丑数 。

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

示例 1:

输入:n = 10
输出:12
解释:[1, 2, 3, 4, 5, 6, 8, 9, 10, 12] 是由前 10 个丑数组成的序列。
示例 2:

输入:n = 1
输出:1
解释:1 通常被视为丑数。

提示:

1 <= n <= 1690

解法1 三指针

class Solution {
    public int nthUglyNumber(int n) {
        
        int[] res = new int[n]; //包含从小到大排列的n个丑数,且不重复
        res[0] = 1;
        //每一个丑数都可由比自己小的丑数乘2,或乘3,或乘5得到
        int a = 0, b = 0, c = 0; 
        //res[i] = res[a] * 2 或 res[b] * 3 或 res[b] * 5
        //由于res[a] * 2,  res[b] * 3,  res[b] * 5可能相等
        //通过res[i] = Min(res[a] * 2, res[b] * 3, res[b] * 5),并令对应的指针+1,就可保证res[]递增且不重复
        for (int i = 1; i < n; i++) { //计算下一个丑数res[i]的值,并更新对应的指针
            int n2 = res[a] * 2, n3 = res[b] * 3, n5 = res[c] *5;
            res[i] = Math.min(Math.min(n2, n3), n5);
            if (res[i] == n2) a++;
            if (res[i] == n3) b++;
            if (res[i] == n5) c++;
        }
        return res[n - 1];
     }
}

解法2 优先权队列

class Solution {
    public int nthUglyNumber(int n) {
        //优先权队列存储生成的丑数,丑数越小优先级越高(借助优先权队列自动排序的特点)
        PriorityQueue<Long> queue = new PriorityQueue<>();
        //answer用于取出丑数,保证每次取出的丑数都不相同
        long answer = 1; //第一取出的个丑数
        //循环取出第2个至第n个丑数
        for (int i = 1; i < n; i++) {
            //生成新的丑数,并添加至队列
            queue.add(answer * 2);
            queue.add(answer * 3);
            queue.add(answer * 5);
            //从队列中取出最小的丑数
            answer = queue.poll();
            //如果队列中的下一个丑数和当前的丑数相同,就将其从队列中移除
            while (!queue.isEmpty() && answer == queue.peek()) {
                queue.poll();
            }
        }
        return (int)answer;

     }
}
posted @ 2025-04-22 22:36  Nickey103  阅读(22)  评论(0)    收藏  举报