設計一個演算法,找出只含素因子2,3,5 的第 n 小的數
阿新 • • 發佈:2019-02-15
醜數為值只包含因子 2、 3、 5 的數,14不是醜數因為包含因子7.
/*int min(int a,int b){
if(a>b){
return b;
}else{
return a;
}
}*/C++中存在min函式,可以直接使用
int nthUglyNumber(int n) {
int num[n+1];
int p2,p3,p5;
p2=p3=p5=0;
num[0]=1;
for (int i=1;i<n;i++)
{
num[i]=min(min(num[p2]*2,num[p3]*3),min(num[p2]*2,num[p5]*5));
if(num[i]==num[p2]*2)
++p2;
if(num[i]==num[p3]*3)
++p3;
if(num[i]==num[p5]*5)
++p5;
}
return num[n-1 ];
}
1.
當前醜數必定是之前某個醜數 k 的 2倍、3倍、或者 5倍。
設定一個整型陣列num[]存放醜數,當前醜數為2*num[p2],3*num[p3],5*num[p5]中的最小值,其中p2,p3,p5之前第p2,p3,p5個醜數,p2,p3,p5初值均為0。
2.
設陣列第一個數值num[0]=1,分別用2,3,5乘1尋找第二個醜數,得到最小值2作為第二個醜數即num[1]=2。
2*num[p2]=2*num[0]=2*1=2
3*num[p3]=3*num[0]=3*1=3
5*num[p5]=5*num[0]=5*1=5
因為第二個醜數是2與上一個醜數相乘得到的,因此在下一次尋找醜數時不需要再計算2與對應相乘的上一個醜數num[p2]相乘,因為下一個醜數一定大於num[1]即2*num[0]。所以在下一次計算醜數時,直接從nun[1]開始乘以2,即p2進一位。
3.
分別用2*num[p2],3*num[p3],5*num[p5]判斷第三個醜數,p2=1,p3=p5=0.
2*num[p2]=2*num[1]=2*2=4
3*num[p3]=3*num[0]=3*1=3
5*num[p5]=5*num[0]=5*1=5
得到最小值3作為第三個醜數,因此在下一次尋找醜數時不需要再計算3與對應相乘的上一個醜數num[0]相乘,因為下一個醜數一定大於3*num[0]即num[2]。所以在下一次計算醜數時,直接從num[1]乘以3,即下表p3進一位。
4.以此類推找到第n個最小值為第n個醜數。