题目:
求按从小到大的第1500个丑数。
丑数:
只包含因子2,3,5的数称为丑数。所谓一个数m是另一个数n的因子,是指n能被m整除。
例:
解1:直观解法,从1开始计算,然后计数,直到第1500个丑数
缺陷:每个整数都需要计算,效率非常低
//判断是不是丑数
bool IsUflyNum(int num)
{
if (num <= 0)
{
return false;
}
while (num % 2 == 0)
{
num = num / 2;
}
while (num % 3 == 0)
{
num = num / 3;
}
while (num % 5 == 0)
{
num = num / 5;
}
//要求不能有除了2,3,5之外的因子
return (num == 1) ? true: false;
}
int GetNum(int n) //此处n代表第n个丑数
{
if (n <= 0)
{
return 0;
}
int count = 0;
int i = 1;
while (1)
{
if (count <= n)
{
if (IsUflyNum(i) == 1) //说明此时的i为丑数
{
count++;
}
}
if (count == n)
{
return i;
}
++i;
}
}
void TestUglyNum()
{
int tty = GetNum(1500);
cout << tty << endl;
}
解2: 用空间换时间
缺陷:需要额外开辟空间来存储丑数
int Min(int num2, int num3, int num5) //返回三个数中的最小的
{
int temp = (num2 < num3) ? num2 : num3; //先找出num2,num3中的最小值
return (temp < num5) ? temp : num5;
}
int GetUglyNum(int n) //此处n代表为第n个丑数
{
if (n <= 0)
{
return 0;
}
int* temp = new int[n]; //开辟一个大小为n的数组存放排序的丑数
assert(temp); //判断数组空间是否开辟成功
for (int i = 0; i < n; ++i)
{
temp[i] = 0;
}
int* ptr2 = temp;
int* ptr3 = temp;
int* ptr5 = temp;
temp[0] = 1; //第一个丑数为1,不用计算
int index = 1; //当前数组下标
while (index < n)
{
//比较三个指针指向位置的值分别乘以2,3,5,取最小值存储
int min = Min((*ptr2) * 2, (*ptr3) * 3, (*ptr5) * 5); //此时找到三个数里面的最小值
temp[index] = min;
index++;
while (min >= (*ptr2) * 2)
{
++ptr2;
}
while (min >= (*ptr3) * 3)
{
++ptr3;
}
while (min >= (*ptr5) * 5)
{
++ptr5;
}
}
int tty = temp[n - 1];
delete[] temp;
return tty;
}
void TestUglyNum()
{
int tty = GetUglyNum(1500);
cout << tty << endl;
}