编程题第五题:
只能被2,3,5之内的素数整数的数是丑数,例如6,8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做是第一个丑数。写出第1499个丑数,说明算法和时间复杂度
解决思路1:
用暴力破解思想,判断每个数是否是丑数,直到判断第1499位
代码:
#include <stdio.h>
int function(int s){
int i=s;
while (i % 2 == 0)
i = i / 2;//不断往下除即可
while (i % 3 == 0)
i = i / 3;
while (i % 5 == 0)
i = i / 5;
if (i == 1)
return 1;
return 0;
}
int main(){
int i;
int count = 0;
for (i = 1;; i++){
if(function(i))
count++;
if (count == 1499)
break;
}
printf("%d", i);
return 0;
}
很明显,超时了
解决思路2:
其实,我们可以观察到,每产生新的一个丑数,它必然是前面的某个丑数*2,
或者 *3,再或者*5,只需在这三个数找到最小的(因为我们要得到有序的丑数)
,那么我们就定义三个下标,最初下标为1,
这三个下标(1个乘以2,一个乘以3,一个乘以5)很快就能得到第2个丑数,
这三个下标变化的标准是,若当前的下标乘以对应数,大于刚加入的丑数,
则不变,否则加1
代码:
#include <stdio.h>
long min(long a,long b,long c){
long min=a;
if(b<min)
min=b;
if(c<min)
min=c;
return min;
}
int main(){
long number[1500];//long型数据范围会比较大
int index2=1;
int index3=1;
int index5=1;
int index=1;
number[1]=1;
while(index<=1499){
long m=min(number[index2]*2,number[index3]*3,number[index5]*5);
number[++index]=m;
if(number[index2]*2<=m)//当大于它时,不用加一
index2++;
if(number[index3]*3<=m)
index3++;
if(number[index5]*5<=m)
index5++;
}
printf("%ld\n",number[1499]);
return 0;
}