我们把只包含质因子2,3,5的数称作丑数,求按从小到大顺序的第n个丑数。
实例:
输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12
是前 10 个丑数。
动态规划问题,需要考虑dp[n]和前几个数的关系。首先明确,所有的丑数都可以由前面的丑数乘以2、3、5这几个质因子得到后面的丑数。由1开始,1*2,1*3,1*5,这几个数肯定为丑数。所以第二个丑数为2,第三个为3。考虑第四个,由于要按照大小顺序,所以第四个数为2*2,第五个才为1*5。随后是3*2,可以看到,每个dp里的数,对于2、3、5这几个质因子只能使用一次。所以对于2,3,5每个数,需要维护一个数字,来记录下一个该与质因子相乘的数的下标(即记录哪些数字已经用过了)
dp[]用于记录丑数,p2,p3,p5用于记录下一个该与质因子相乘的数组下标。num2,num3,num5用于记录相乘后得到的丑数。dp[n]为num2,num3,num5中最小的一个。每当得到一个丑数后,对应的质因子对应的数组下标+1,表示该数已经用过。
class Solution {
public int nthUglyNumber(int n) {
int[] dp=new int[n+1];
int p2=1,p3=1,p5=1;
dp[1]=1;
int num2,num3,num5;
for(int i=2;i<=n;i++){
num2=dp[p2]*2;num3=dp[p3]*3;num5=dp[p5]*5;
dp[n]=Math.min(Math.min(num2,num3),num5);
if(dp[n]=num2){
p2++;
}
if(dp[n]=num3){
p3++;
}
if(dp[n]=num5){
p5++;
}
}
return dp[n];
}
}