丑数

题目描述

把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。

思考

若判断一个数是不是丑数,可以知道一个丑数必然可以写成2^n1*3^n2*5^n3的形式,所以对一个数判断,可以不断分别对2,3,5取余,如果最后剩下的数为1则为丑数,否则则不是丑数。判断一个丑数的时间复杂度为O(lgn),求出第N个的时间复杂度为O(n*lgn);
另一种思考:
1.我们知道下一个丑数必定是前面的某个丑数的2,3,5的倍数,但是不确定是哪个。
2.丑数是不断递增的
3.1也是一个丑数
我们可以设定大小为N的数组,第一个数字为1。此时我们要求第二个丑数,我们很容易想到从1*2,1*3,1*5中选择,于是有2;
接下来,第三个丑数,可以想到是2*2,1*3,1*5中选择,于是有3;
所以我们可以设置三个指针point2,point3,point3,最开始都指向数组首元素,取指针指向的数分别乘以2,3,5,判断其是否大于当前数组最大元素,若否则指针前移,直到达到目标为止。于是此时我们可以得到三个数,只需要从这三个数中选取最小的数就可以。我们直到此时算法的时间复杂度大概为O(n);
代码如下:

int GetUglyNumber_Solution(int index) {

    int ans[index];
    ans[0]=1;
   int *point2,*point3,*point5;
    point2=&ans[0];point3=&ans[0];point5=&ans[0];
    int nextindex=1;
    while(nextindex<index)
        {
        while((*point2)*2<=ans[nextindex-1])
            ++point2;
            while((*point3)*3<=ans[nextindex-1])
                ++point3;
        while((*point5)*5<=ans[nextindex-1])
            ++point5;
            ans[nextindex++]=Min((*point2)*2,(*point3)*3,(*point5)*5);
    }

  return ans[index-1];
}
int Min(int Num1,int Num2,int Num3)
{
    if(Num1<Num2)
    {
        if(Num2<Num3)
            return Num1;
        else
            return Num1<Num3?Num1:Num3;
    }
    else
    {
        if(Num1<Num3)
            return Num2;
        else
            return Num2<Num3?Num2:Num3;
    }}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值