您的位置:首页 > Web前端

剑指offer的34题 丑数

2014-04-04 21:10 204 查看
我们把只包含因子2、3和5的数称为丑数(Ugly Number)。求从小到大的顺序的第1500个丑数。习惯上我们把1当做第一个丑数。

这道题暴力的解法就是按照顺序检查每一个数是不是丑数。

判断一个数是不是丑数的函数如下:

bool IsUglyNumber(int num)

{

while(num%2==0)

num/=2;

while(num%3==0)

num/=3;

while(num%5==0)

num/=5;

returnnum==1?true:false;

}


从1开始,按顺序检查,如果这个数是丑数,加1,直到1500个丑数为止。

int GetUglyNumber1(int index)

{

if(index<1)

return0;

intnumber=0;

intcount=0;

while(count<index)

{

number++;

if(IsUglyNumber(number))

++count;

}

returnnumber;

}


这个代码非常整洁,但最大的问题每一个整数都需要计算。即使这个数字不是丑数,我们还是需要对它进行求余和除法操作。该算法的效率是很低的。

我们应该试着找到一种只需要计算丑数的方法,而不需要在非丑数的整数上面花费时间。根据丑数的定义,丑数应该是另一个丑数乘以2、3、5的结果(1除外)。因此我们可以创建一个数组,里面的数字是排好序的丑数,每一个丑数都是前面的丑数乘以2、3或者5得到。

int min(int a,int b,int c)

{

intmin=a<b?a:b;

returnmin<c?min:c;

}

int GetUglyNumber2(int index)

{

if(index<1)

return0;

int*pUglyNumbers=new int[index];

pUglyNumbers[0]=1;

intnextIndex=1;

int*pUgly2=pUglyNumbers;

int*pUgly3=pUglyNumbers;

int*pUgly5=pUglyNumbers;

while(nextIndex<index)

{

pUglyNumbers[nextIndex]=min(*pUgly2*2,*pUgly3*3,*pUgly5*5);

while(*pUgly2*2<=pUglyNumbers[nextIndex])

++pUgly2;

while(*pUgly3*3<=pUglyNumbers[nextIndex])

++pUgly3;

while(*pUgly5*5<=pUglyNumbers[nextIndex])

++pUgly5;

++nextIndex;

}

intugly=pUglyNumbers[nextIndex-1];

delete[]pUglyNumbers;                //将数组内存释放掉

returnugly;

}


这种方法需要一定的内存空间,是一种以空间换时间的思想。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  丑数