剑指 Offer 49. 丑数
题目描述
我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。
解答
class Solution {
/**
动态规划五部曲:
确定dp数组及其下标的含义
dp[i]代表第i+1个丑数
确定递推公式
丑数的递推性质:因为丑数只含质因子2、3和5所以,丑数 = 某较小丑数 × 某因子
所以,丑数dp[i]只有可能为dp[a] * 2、dp[b] * 3、dp[c] * 5这三种情况中的一个
而且,dp[a]、dp[b]、dp[c]需要满足
dp[a] * 2 > dp[i-1] >= dp[a-1] * 2,即dp[a]为首个乘以2之后大于dp[i-1]的丑数
dp[b] * 3 > dp[i-1] >= dp[b-1] * 3,即dp[b]为首个乘以3之后大于dp[i-1]的丑数
dp[c] * 5 > dp[i-1] >= dp[c-1] * 5,即dp[c]为首个乘以5之后大于dp[i-1]的丑数
因为是求从小到大的顺序的第n个丑数
所以dp[i] = Math.min{dp[a] * 2,dp[b] * 3,dp[c] * 5},dp[a],dp[b],dp[c]满足上述条件
如何对dp数组进行初始化
dp[0] = 1;
确定遍历序列
从前往后
对dp数组进行输出
*/
public int nthUglyNumber(int n) {
int[] dp = new int[n];
int a=0,b=0,c=0;
dp[0] = 1;
for(int i = 1;i < n;i++){
//一开始a,b,c=0自然满足首个的条件
dp[i] = Math.min(dp[a]*2,Math.min(dp[b]*3,dp[c]*5));
//为了让dp[a]、dp[b]、dp[c]满足为首个的条件
if(dp[i] == dp[a]*2){
a++;
}
if(dp[i] == dp[b]*3){
b++;
}
if(dp[i] == dp[c]*5){
c++;
}
}
return dp[n-1];
}
}