丑数(23)

题目

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


方法一:
1、分析
如果使用遍历每个数的方式,则会大大的降低效率。所以采用空间换时间的方式,将所有的丑数进行排序,然后直接可以用 o ( 1 ) o(1) 的时间复杂度来查出第N个丑数。
因为丑数的质因子只有2或3或5,所以可以得到所有的丑数都是由前面的丑数乘以2或者3或者5得到的。因此创建一个数组用来存放这些排好序的丑数。假设当前的丑数为Num,则下一个丑数就是该丑数前面的丑数乘以235所得到的结果中最小的那个丑数,且其大于Num。同时用k2、k3、k5来记录上次计算丑数时分别用来乘以235的位置。
2、代码

class Solution {
public:
    int GetUglyNumber_Solution(int index) {
        if(index<=0)
            return 0;
        //因为1~6都是丑数,所以可以直接返回其值
        if(index<7)
            return index;
        int *temp=new int[index];
        temp[0]=1;
        int k2=0,k3=0,k5=0;
        for(int i=1;i<index;++i)
        {
            temp[i]=min(temp[k2]*2,temp[k3]*3,temp[k5]*5);
            //若当前丑数为k2位置的丑数乘以2,则下一次再乘以2之前,k2的位置必须前移一下
            if(temp[i]==temp[k2]*2)
                ++k2;
            if(temp[i]==temp[k3]*3)
                ++k3;
            if(temp[i]==temp[k5]*5)
                ++k5;
        }
        return temp[index-1];
    }
    
    int min(int a,int b,int c)
    {
        int tmp=(a<b)?a:b;
        return (tmp<c)?tmp:c;
    }
};

方法二:
从1开始,遍历每个数,并判断其是否为丑数。若是就将序列进行自加,直到第 N 个丑数。该方法效率低,对不是丑数的数字也进行了大量的计算判断。

class Solution {
public:
    int GetUglyNumber_Solution(int index) {
        if(index<=0)
            return 0;
        int Num=0;
        int theOrder=0;
        while(theOrder<index)
        {
            ++Num;
            if(IsUglyNumber(Num))
            {
                ++theOrder;
            }
        }
        return Num;
    
    }
    // 判断是否为丑数的方法
    bool IsUglyNumber(int num)
    {
        while(num%2==0)
            num/=2;
        while(num%3==0)
            num/=3;
        while(num%5==0)
            num/=5;
        
        return (num==1)?true:false;
    }
};
发布了213 篇原创文章 · 获赞 48 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/Jeffxu_lib/article/details/104745272