小米oj
这个题目的数据比较刁钻。。。
第N个丑数
描述
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
输入
输入一个正整数N,0<N<10000
输出
输出一个正整数S,S为第N个丑数
解题思路
输出
首先尝试一种比较常规的做法,对从1开始的每个数进行遍历,查看是不是一个丑数,具体做法就是,把这个数分别整除2,3,5,知道不能除为止。最后剩下的数如果是1,那么这个数就是丑数。具体代码如下
int hxnb(int n)//输入是n判断n是不是丑数
{
while (n % 2==0)
n /= 2;
while (n % 3==0)
n /= 3;
while (n % 5==0)
n /= 5;
if (n == 1)
return 1;
else
return 0;
}
然而这种做法时间复杂度为n*logn所以时间所以时间上很长,抱着侥幸的心理。结果。。。。。。。果然不行。。。显示超时。。。
然后就不得不用另一种办法。每一个新出现的丑数一定是前面的丑数乘2,3或者是5来得到的,我们可以只找第一个比现在最大丑数大的丑数,不用去遍历哪些一定不是丑数的,时间上能够得到不小的提升。具体实现如下
long long hxnb(long long n)//第n个丑数是多少
{
//int * ugly = (int*)calloc(3000,sizeof(int));
long long ugly[6000] = {};
ugly[0] = 1;//第一个丑数为1
int index2 = 0;
int index3 = 0;
int index5 = 0;
int index = 1;
while (index<n)
{
long long val = min_h(ugly[index2] * 2, ugly[index3] * 3, ugly[index5] * 5);
if (val == ugly[index2] * 2)
index2++;
if (val == ugly[index3] * 3)
index3++;
if (val == ugly[index5] * 5)
index5++;
ugly[index++] = val;
// printf("val =%d %d %d %d\r\n", val,index2,index3,index5);
}
// free(ugly);
return ugly[index-1];
}
这里有一个细节,一开始全部用的int,然而int的范围是-2147483648 ~ 2147483647,所以当N是1000多的时候就根本不行。。。。迫不得已,所以的数据选用long long类型。终于顺利通过。。。