題目
【把只包含質因子2、3和5的數稱作醜數(Ugly Number)。例如6、8都是醜數,但14不是,因爲它包含質因子7。 習慣上我們把1當做是第一個醜數。求按從小到大的順序的第N個醜數】
方法一:
1、分析
如果使用遍歷每個數的方式,則會大大的降低效率。所以採用空間換時間的方式,將所有的醜數進行排序,然後直接可以用的時間複雜度來查出第N個醜數。
因爲醜數的質因子只有2或3或5,所以可以得到所有的醜數都是由前面的醜數乘以2或者3或者5得到的。因此創建一個數組用來存放這些排好序的醜數。假設當前的醜數爲Num,則下一個醜數就是該醜數前面的醜數乘以2或3或5所得到的結果中最小的那個醜數,且其大於Num。同時用k2、k3、k5來記錄上次計算醜數時分別用來乘以2、3、5的位置。
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;
}
};