题目
【把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数】
方法一:
1、分析
如果使用遍历每个数的方式,则会大大的降低效率。所以采用空间换时间的方式,将所有的丑数进行排序,然后直接可以用
的时间复杂度来查出第N个丑数。
因为丑数的质因子只有2或3或5,所以可以得到所有的丑数都是由前面的丑数乘以2或者3或者5得到的。因此创建一个数组用来存放这些排好序的丑数。假设当前的丑数为Num,则下一个丑数就是该丑数前面的丑数乘以2或3或5所得到的结果中最小的那个丑数,且其大于Num。同时用k2、k3、k5来记录上次计算丑数时分别用来乘以2、3、5的位置。
2、代码
class Solution {
public:
int GetUglyNumber_Solution(int index) {
if(index<=0)
return 0;
//因为1~6都是丑数,所以可以直接返回其值
if(index<7)
return index;
int *temp=new int[index];
temp[0]=1;
int k2=0,k3=0,k5=0;
for(int i=1;i<index;++i)
{
temp[i]=min(temp[k2]*2,temp[k3]*3,temp[k5]*5);
//若当前丑数为k2位置的丑数乘以2,则下一次再乘以2之前,k2的位置必须前移一下
if(temp[i]==temp[k2]*2)
++k2;
if(temp[i]==temp[k3]*3)
++k3;
if(temp[i]==temp[k5]*5)
++k5;
}
return temp[index-1];
}
int min(int a,int b,int c)
{
int tmp=(a<b)?a:b;
return (tmp<c)?tmp:c;
}
};
方法二:
从1开始,遍历每个数,并判断其是否为丑数。若是就将序列进行自加,直到第 N 个丑数。该方法效率低,对不是丑数的数字也进行了大量的计算判断。
class Solution {
public:
int GetUglyNumber_Solution(int index) {
if(index<=0)
return 0;
int Num=0;
int theOrder=0;
while(theOrder<index)
{
++Num;
if(IsUglyNumber(Num))
{
++theOrder;
}
}
return Num;
}
// 判断是否为丑数的方法
bool IsUglyNumber(int num)
{
while(num%2==0)
num/=2;
while(num%3==0)
num/=3;
while(num%5==0)
num/=5;
return (num==1)?true:false;
}
};