题目链接
丑数 II
题目描述
![](https://i-blog.csdnimg.cn/direct/9ee8599c719a499a8aa85fdf600523c7.png)
注意点
- 1 <= n <= 1690
- 1 通常被视为丑数
- 丑数 就是质因子只包含 2、3 和 5 的正整数
解答思路
- 初始想到的是使用最小堆,根据本次堆中的最小元素将其分别乘以2、3、5加入到堆中,找到第n小的数即可,需要注意的是,如2 * 3、3 * 2的情况结果相同会往堆中添加多次,所以还需要使用哈希表存储元素是否已经添加到堆中
- 上述方法比较简单,但是因为要使用哈希表存储添加过的元素,所以空间复杂度并不好,并且相同的丑数可能会判断多次,所以时间上也不理想
- 参考题解可以使用动态规划解决本题,dp[i]代表是第i小的丑数,初始dp[0] = 1,有三个指针p2、p3、p5分别指向质因子为2、质因子为3、质因子为5的丑数,每次将指针乘以质因子,并取三者中最小的一个作为新的丑数,并令该指针加一。这样做保证dp[i]是第i小的丑数,同时重复的丑数会在某次选择最小数时同时剔除掉
代码
class Solution {
public int nthUglyNumber(int n) {
int[] dp = new int[n];
dp[0] = 1;
int p2 = 0;
int p3 = 0;
int p5 = 0;
for (int i = 1; i < n; i++) {
int num2 = dp[p2] * 2;
int num3 = dp[p3] * 3;
int num5 = dp[p5] * 5;
int minVal = Math.min(Math.min(num2, num3), num5);
dp[i] = minVal;
if (minVal == num2) {
p2++;
}
if (minVal == num3) {
p3++;
}
if (minVal == num5) {
p5++;
}
}
return dp[n - 1];
}
}
关键点