题目描述
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
代码如下
int Min(int a, int b, int c);
//顺次加1递归版
bool IsUglyNumber(int number)
{
if(number == 2 || number == 3 || number == 5) return true;
if(number%2 == 0)
IsUglyNumber(number / 2);
else if(number%3 == 0)
IsUglyNumber(number / 3);
else if(number%5 == 0)
IsUglyNumber(number / 5);
else
return false;
}
//顺次加1迭代版
bool IsUglyNumber2(int number)
{
while(number%2 == 0)
number /=2 ;
while (number%3 == 0)
number /= 3;
while(number%5 == 0)
number /= 5;
return (number == 1) ? true : false;
}
//低效率版
int GetUglyNumber_Solution3(int index)
{
if(index < 1) return 0;
if(index == 1) return 1;
int i = 2;
index -= 1;
while(index != 0)
{
while(true)
{
if(IsUglyNumber(i)) break;
i++;
}
i++;
index--;
}
return i;
}
//高效率版,从前往后推,分别找出前n个数字中乘2、3、5中最小的值,即为下一个丑数
int GetUglyNumber_Solution(int index)
{
if(index <= 0) return 0;
int *pUgly = new int[index];
pUgly[0] = 1;
int pNext = 1;
int* pm2 = pUgly;
int* pm3 = pUgly;
int* pm5 = pUgly;
while(pNext < index)
{
int min = Min(*pm2 * 2, *pm3 * 3, *pm5 * 5);
pUgly[pNext] = min;
while(*pm2 * 2 <= pUgly[pNext]) //pm2指向的值前的所有值乘2皆小于下一丑数
++pm2;
while(*pm3 * 3 <= pUgly[pNext]) //pm3指向的值前的所有值乘3皆小于下一丑数
++pm3;
while(*pm5 * 5 <= pUgly[pNext]) //pm5指向的值前的所有值乘5皆小于下一丑数
++pm5;
++pNext;
}
int ugly = pUgly[pNext-1];
delete[] pUgly;
return ugly;
}
int Min(int a, int b, int c)
{
int min = (a < b) ? a : b;
return (min < c) ? min : c;
}
void GetUlgyNumberTest()
{
int index = 3;
int ugly = GetUglyNumber_Solution(index);
}