1.我们把只包含因为2,3,5的数称为丑数,求从小到大的顺序的第1500个丑数,例如6,8都是丑数,但14不是,因为含有因子7.
分析:
常规的做法:逐个判断每个数是不是丑数,统计个数,找到第1500个丑数,方法比较慢。
快速解法:根据丑数的定义,丑数应该是另一个丑数乘以2,3或者5的结果,因此可以构建这样一个数组,里面是排序好的丑数,每一个丑数都是前面的丑数乘以2,3或者5得到的。假设数组中已经有了若干个丑数了,最大的丑数是M,下面一个丑数的产生就是前面的数乘以2,3,或者5的结果。假若不做判断的话,就是将所有的数分别乘以2,3,5,然后找出其中最小的那个数,但是会发现相乘的结果中很多已经出现在前面的数中了,所以也不能完全的所有的数都乘以2,3,5,而是有选择的乘,这就涉及到什么时候,什么位置的数乘以2,什么位置的数乘以3,什么位置的数乘以5 了,然后取这3个数中的最小值作为下一个丑数。
源码:
/**
* 功能说明:Description
* 作者:K0713
* 日期:2016-9-1
**/
#include<iostream>
using namespace std;
//循环相除判断是否是丑数
bool IsUgly(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;
}
//从1开始找到第1500个丑数
int GetUglyNumber_Solution1(int index)
{
if (index <= 0)
return 0;
int number = 0;
int uglyFound = 0;
while (uglyFound < index)
{
++number;
if (IsUgly(number))
{
++uglyFound;
}
}
return number;
}
//通过丑数找下一个丑数
int Min(int number1, int number2, int number3);
int GetUglyNumber_Solution2(int index)
{
if (index <= 0)
return 0;
int *pUglyNumbers = new int[index];
pUglyNumbers[0] = 1;
int nextUglyIndex = 1;
int *pMultiply2 = pUglyNumbers;
int *pMultiply3 = pUglyNumbers;
int *pMultiply5 = pUglyNumbers;
while (nextUglyIndex < index)
{
int min = Min(*pMultiply2 * 2, *pMultiply3 * 3, *pMultiply5 * 5);
pUglyNumbers[nextUglyIndex] = min;
//标定位置
while (*pMultiply2 * 2 <= pUglyNumbers[nextUglyIndex])
++pMultiply2;
while (*pMultiply3 * 3 <= pUglyNumbers[nextUglyIndex])
++pMultiply3;
while (*pMultiply5 * 5 <= pUglyNumbers[nextUglyIndex])
++pMultiply5;
++nextUglyIndex;
}
int ugly = pUglyNumbers[nextUglyIndex - 1];
delete[] pUglyNumbers;
return ugly;
}
int Min(int number1, int number2, int number3)
{
int min = (number1 < number2) ? number1 : number2;
min = (min < number3) ? min : number3;
return min;
}
int main()
{
int result1 = GetUglyNumber_Solution1(100);
cout << "result is :" << result1 << endl;
int result2 = GetUglyNumber_Solution2(1500);
cout << "result is :" << result2 << endl;
system("PAUSE");
return 0;
}