题目
给你一个整数 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 通常被视为丑数。
代码
解法一
使用之前的丑数判断函数,判断出每一个丑数并且设置一个count来记录当前丑数的个数,当count等于n时返回当前数字。
var isUgly = function(n) {
while (n>1){
if (n%2==0){n/=2;};
if (n%3==0){n/=3;};
if (n%5==0){n/=5;};
if (n%2 && n%3 && n%5 && n!=1){return false};
}
return true;
};//判断i是否为丑数的函数
var nthUglyNumber = function(n) {
var i = 1;//设置一个变量来记录当前判断的数
var count = 0;//记录丑数的个数
while (count!=n){
if (isUgly(i)){
count++;//如果i是丑数则count加一
}
i++;//使i自增实现遍历
}
return i -1
}
此方法时间复杂度过高,没有通过leecode的测试不推荐。
解法二
因为丑数只是因数只有2,3,5的数;
所以我们使用三个指针p2,p3,p5,表示下一个丑数是当前指针指向的丑数乘以对应的质因数。
并且设置一个dp数组表示当前已经找出并排列好的丑数数组;
var nthUglyNumber = function(n) {
const dp = new Array(n + 1).fill(0);//创建一个伪数组来保存丑数
dp[1] = 1;//将第一个丑数1直接存入
let p2 = 1,p3 = 1,p5 = 1;//设置三个指针来表示各个质因数的下一个丑数是当前指针指向的丑数乘以对应的质因数。
for (let i = 2; i <= n; i++) {
const num2 = dp[p2]*2;//保存三个质因数当前的丑数
const num3 = dp[p3]*3;
const num5 = dp[p5]*5;
dp[i] = Math.min(Math.min(num2,num3),num5);//将当前三个最小丑数存入dp中
if (dp[i]==num2){
p2++;//如果dp[i]是当前2的质因数的丑数,2的指针加一
}
if (dp[i]==num3){
p3++;
}
if (dp[i]==num5){
p5++;
}
}
return dp[n];
}