题目描述:
设计一个算法,找出只含素因子2,3,5 的第 n 小的数。
符合条件的数如:1, 2, 3, 4, 5, 6, 8, 9, 10, 12...
样例
如果n = 9, 返回 10
挑战
要求时间复杂度为O(nlogn)或者O(n)
注意事项
我们可以认为1也是一个丑数
代码如下:
1.使用暴力破解,但是编译不通过,时间复杂度不满足要求
class Solution {
public:
int nthUglyNumber(int n) {
int j;
int number = 2;
if(n==1)
{
return 1;
}
while(n!=j)
{
if(number%2==0)
j++;
if(number%3==0)
j++;
if(number%5==0)
j++;
if(number%6==0)
j++;
if(number%10==0)
j++;
if(number%15==0)
j++;
if(number%30==0)
j++;
else
number++;
}
return number;
}
};
2. 直接去寻找丑数,任何一个丑数均是由2^i * 3^j * 5^k生成的,按从小到大顺序排列,从而确定丑数。
首先定义一个数组存放丑数:int *UglyNumber = new int[n];
由于1也是丑数,故初始化数组 :UglyNumber[0] = 1;
然后在2,3,5中进行挑选,即选择UglyNumber[0]*2、UglyNumber[0]*3、UglyNumber[0]*5三个数中最小的最为第二个丑数,三个公式的计算结果为2,3,5,故最小的是2,即 UglyNumber[1]=2,则 num_2++; ------>num_2=1
接着继续查找,即在4,3,5中寻找最小的,即UglyNumber[1]*2、UglyNumber[0]*3、UglyNumber[0]*5,三个公式结果为上述的4,3,5,最小的是3,即UglyNumber[2]=3,则num_3++;-------->num_3=1
接下来在4,6,5中寻找最小的,即UglyNumber[1]*2、UglyNumber[1]*3、UglyNumber[0]*5计算结果对应的数,最小的是4,则UglyNumber[3]=4,则 num_2++; -------> num_2=2
以此类推:
可得任意第n个丑数对应的值 :UglyNumber[n-1]
代码如下:
class Solution
{
public:
int nthUglyNumber(int n)
{
int *UglyNumber = new int[n]; //定义一个存放丑数的数组
UglyNumber[0] = 1; //初始化丑数数组,因为1算是丑数
int num_2 = 0;
int num_3 = 0;
int num_5 = 0;
int i;
for(i=1;i<n;i++)
{
UglyNumber[i] = min(min(UglyNumber[num_2]*2,UglyNumber[num_3]*3),UglyNumber[num_5]*5);
if(UglyNumber[i] / UglyNumber[num_2] == 2)
num_2++;
if(UglyNumber[i] / UglyNumber[num_3] == 3)
num_3++;
if(UglyNumber[i] / UglyNumber[num_5] == 5)
num_5++;
}
return UglyNumber[n-1];
}
};