醜數(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;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章