int nthUglyNumber(int n){
int p2=1, p3=1, p5=1;
int dp[n+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[i] = fmin(fmin(num2,num3),num5);
if(dp[i] == num2){
p2++;
}
if(dp[i] == num3){
p3++;
}
if(dp[i] == num5){
p5++;
}
}
return dp[n];
}
采用动态规划官方解法:
https://leetcode-cn.com/problems/ugly-number-ii/solution/chou-shu-ii-by-leetcode-solution-uoqd/
设dp[i]为第i个丑数,dp[1]=1,设置初值为1的三指针p2,p3,p5
dp[i]=min(dp[p2]*2,dp[p3]*3,dp[p5]*5);
如果最小值是dp[pi]*i,则pi++
具体过程如下:
p2 | p3 | p4 | dp[n] |
1 | 1 | 1 | dp[2]=min(2,3,5)=2 |
2 | 1 | 1 | dp[3]=min(4,3,5)=3 |
2 | 2 | 1 | dp[4]=min(4,6,5)=4 |
3 | 2 | 1 | dp[5]=min(6,6,5)=5 |
3 | 2 | 2 | dp[6]=min(6,6,10)=6 |
4 | 3 | 2 | dp[7]=min(8,9,10)=8 |
可以看出,dp[pi]*i(i=2,3,5) 分别构成三个以2,3,5为因数的递增数列,每次选取其中较小的那个作为下一个丑数,然后将被选取的那列乘以i然后加入下一次运算。也就是相当于把三个递增数组合并成一个递增数组,以此保证选出的丑数实现单调递增
注意当dp[pi]*i中存在相等结果时,对应的pi都需要++,例如表中n=6的情况