题意:找出第n个Ugly number。 那么什么是Ugly number呢? 也就是一个数的质因数只能是2,3或5。比如,7 就不是,15=3*5 就是。 同时,1也被看作是Ugly number。
题解:首先求一个数是不是Ugly number,我们可以用递归的方法求,也就是将一个数能被2,3,5 整除,那么就一直除,如果最后得1,说明是Ugly number,否则不是。
代码如下:
bool isUgly(int num) {
if( num <= 0) return false;
while ( num%5 == 0) num /= 5;
while ( num%3 == 0) num /= 3;
while ( num%2 == 0) num /= 2;
return ( num == 1 );
}
现在,难度升级。我们要求出第n个Ugly number。
序 号:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
Ugly数:1 2 3 4 5 6 8 9 10 12 15 16 18 20 24 25 ....
很显然,后面得到的Ugly数都是前面的Ugly数乘2、3或5得到的。 那么,我们就可以定义三个指针p1,p2,p3,其对应三个序列。其中dp[i]表示第i个Ugly数。
1*2 2*2 3*2 4*2 5*2 6*2 8*2 9*2 10*2 12*2 15*2...
1*3 2*3 3*3 4*3 5*3 6*3 8*3 8*3 10*3 12*3 15*3...
1*5 2*5 3*5 4*5 5*5 6*5 8*5 8*5 10*5 12*5 15*5...
那么 dp[i]=min{2*dp[p1],3*dp[p2], 5*dp[p3]},意思就是当前第i个Ugly数等于前面的Ugly数乘以2、3或5 中最小的那个。那么我们就需要知道p1,p2,p3分别指向哪个Ugly数了。
初始状态p1=1,p2=1,p3=1,均为1,表示为第一个ugly数。如果当前的数dp[i]等于2*dp[p1]或3*dp[p2]或5*dp[p3],那么其中的p就会+1,即往后指一个Ugly数。
class Solution {
public:
int nthUglyNumber(int n) {
if(n<=0) return 0;
vector<int> dp(n+1,1);
int p1=1,p2=1,p3=1;
for(int i=2;i<=n;i++){
dp[i]=min(2*dp[p1],min(3*dp[p2],5*dp[p3]));
if(dp[i]==2*dp[p1]) p1++;
if(dp[i]==3*dp[p2]) p2++;
if(dp[i]==5*dp[p3]) p3++;
}
return dp[n];
}
};