您的位置:首页 > 职场人生

剑指Offer----面试题34:丑数

2016-07-31 22:22 381 查看

题目:

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

方法一:

分析:逐个判断整数是不是丑数,直观但是效率低下。

根据丑数的定义,丑数只能被2、3和5整除,也就是说一个数能被2整除,我们把它连续除以2;如果能被3整除,我们将它连续除以3;如果能被5整除,我们将它连续除以5;。如果自后得到1,那么这个数就是丑数。

代码如下:

#include<iostream>
#include<Windows.h>

using namespace std;

//判断一个数是否为丑数
bool isUgly(int num)
{
if (num <= 0)
return false;
while (num % 2 == 0)
num /= 2;
while (num % 3 == 0)
num /= 3;
while (num % 5 == 0)
num /= 5;

return (num == 1) ? true : false;
}

int GetUglyNum(int index)
{
if (index <= 0)
return 0;

int num = 0;//统计个数
int temp = 0;//从第1个数开始判断

while (num < index)
{
++temp;
if (isUgly(temp))
++num;
}

return temp;
}

int main()
{
DWORD start = GetTickCount();
cout << GetUglyNum(1500) << endl;
DWORD used = GetTickCount() - start;
cout << "耗时:" << used << "毫秒" << endl;

system("pause");
return 0;
}
运行结果:

859963392
耗时:38017毫秒
请按任意键继续. . .

注意:这种方法直观,代码简洁,但是最大的问题就是每一个整数都需要计算,因此效率低下。

方法二:





源代码如下:

#include<iostream>
#include<Windows.h>

using namespace std;

int Min(int num1, int num2, int num3)//返回三个数中最小值
{
return (num1 < num2) ? ((num1 < num3) ? num1 : num3) : ((num2 < num3) ? num2 : num3);
}

int GetUglySolution2(int index)
{
if (index <= 0)
return 0;

int *pUglyNumbers = new int[index];//申请内存空间,用来存储丑数
memset(pUglyNumbers, 0, index);//将内存中原始数据置为0
pUglyNumbers[0] = 1;//第一个丑数为1
int nextUglyIndex = 1;

int *M2 = pUglyNumbers;//*M2记录乘以2后的值,M2记录位置,初始时位置相同
int *M3 = pUglyNumbers;
int *M5 = pUglyNumbers;

while (nextUglyIndex < index)
{
int min = Min((*M2) * 2, (*M3) * 3, (*M5) * 5);
pUglyNumbers[nextUglyIndex] = min;//记录当前最大的丑数

//对位置进行重新定位
while (*M2 * 2 <= pUglyNumbers[nextUglyIndex])
++M2;//记录下第一次大于当前最大丑数的M2的位置
while (*M3 * 3 <= pUglyNumbers[nextUglyIndex])
++M3;
while (*M5 * 5 <= pUglyNumbers[nextUglyIndex])
++M5;

++nextUglyIndex;
}

int ugly = pUglyNumbers[nextUglyIndex - 1];
delete[] pUglyNumbers;
return ugly;
}

int main()
{
DWORD start = GetTickCount();
cout << GetUglySolution2(1500) << endl;

DWORD used = GetTickCount() - start;
cout << "耗时:" << used << "毫秒" << endl;

system("pause");
return 0;
}

运行结果:
859963392
耗时:0毫秒
请按任意键继续. . .


分析:
第二种方法效率明显提升,但是其消耗了1500*4*1024 = 6KB的存储空间。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ 剑指Offer 丑数