您的位置:首页 > 其它

寻找丑数(ugly number)

2014-03-11 15:06 288 查看
【问题】

我们把把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第1500个丑数。

【分析】

很自然的我们可以想到使用暴力解法,把1500个丑数从众多数中找出来,如何找出来呢?我们就要判断这个数是否只包含2,3,5这三个因子,我们就将这几个因子全都消除,这样最后如果为丑数,则结果必然为1,否则的话,结果必然不为1,下面是代码:

bool isUglynum(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;
}

int uglyNum(int index){
int num = 2;
int i = 0;
while(i <index){
if(isUglynum(num))
i++;
num++;
}
return num-1;
}


那么,会不会有更简单的方法呢?这个方法的复杂度太高了,而且不断地运用除法,必然会导致算法效率低下。想到我们有时会用空间换取时间的方法提高算法的时间复杂度,那么这个是否也可以这样呢?我们是否可以先存储起来原来已经找打的丑数,然后再计算新的丑数呢?答案是肯定的,我们可以用一个数组按顺序储存起来原来找到的丑数,然后对已经找到的丑数计算它们乘以因子2,3,5,之后的结果,然后从中找到一个最小的,添加到数组后面,这样直到找到指定序号的丑数,代码如下:

int min(int x, int y,int z){
int min = x;
if(y < min)
min = y;
if(z < min)
min = z;
return min;
}

int uglyNum2(int index){
int *array = new int[index + 1];
int *pMin2 = array;
int *pMin3 = array;
int *pMin5 = array;

int i = 0;
array[0] = 1;
while( i < index){
array[++i] = min((*pMin2) * 2, (*pMin3) *3,(*pMin5)*5);
while((*pMin2) * 2 <= array[i])
pMin2++;
while((*pMin3) * 3 <= array[i])
pMin3++;
while((*pMin5) * 5 <= array[i])
pMin5++;
}
int ugly = array[i];
delete array;
return ugly;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: