1. 直接法
public int GetUglyNumber_Solution(int n)
{
if (n < 0)
return 0;
int number = 0;
int uglyFound = 0;
while (uglyFound < n)
{
++number;
if (isUgly(number))
{
++uglyFound;
}
}
return number;
}
/**
* 判断一个数是否是丑数
*
* @param number
* @return
*/
boolean 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;
}
该算法时间复杂度过大,运行超时.
2. 找规律(空间换时间)
根据丑数的定义,丑数应该是另一个丑数乘以2, 3 或 5 的结果(1 除外). 因此,我们可以创建一个数组,里面的数字
是排好序的丑数,每一个丑数都是前面的丑数乘以2, 3, 或5 得到的.
public int GetUglyNumber_Solution(int n)
{
if (n < 0)
return 0;
if (n < 7)
return n;
// 创建一个能够给容纳n各元素的数组
int[] uglyNumbers = new int[n];
uglyNumbers[0] = 1; // 给第一个元素赋初始值
int i2 = 0;
int i3 = 0;
int i5 = 0;
int ncount = 1; // 到目前为止丑数个数
int tmp = 0;
while (ncount < n)
{
tmp = Math.min(Math.min(uglyNumbers[i2]*2, uglyNumbers[i3]*3), uglyNumbers[i5]*5);
uglyNumbers[ncount++] = tmp;
if(tmp == uglyNumbers[i2]*2) // 这里不能用else if
i2++;
if (tmp == uglyNumbers[i3] * 3)
i3++;
if (tmp == uglyNumbers[i5] * 5)
i5++;
}
return uglyNumbers[n-1];
}