Write a program to find the
Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.
Note that 1 is typically treated as an ugly number.
1.The naive approach is to call isUgly for every number until you reach the nth one. Most numbers are not ugly. Try to focus your effort on generating only the ugly ones.
2.An ugly number must be multiplied by either 2, 3, or 5 from a smaller ugly number.
3.The key is how to maintain the order of the ugly numbers. Try a similar approach of merging from three sorted lists: L1, L2, and L3.
4.Assume you have Uk, the kth ugly number. Then Uk+1 must be Min(L1 * 2, L2 * 3, L3 * 5).
找出第n个ugly数。所谓ugly数,即质因子只有2,3,5。即这个数仅通过2,3,5的相乘便可以得到。设1是ugly数。
根据给的线索,如果逐条判断该数是不是ugly,直到找到第n个ugly数。虽然方法行的通,但是由于大部分数都是非ugly的,这样做明显非常耗时。
采用动态规划的思想。每个ugly数都是由2或3或5乘以另外一个ugly数组成。设置三个指针,分别表示乘以2,3或5之前的ugly数。每次选择当前指针所指向位置的最小值,并将适当的某个指针前移一位。指针设为index_2=0, index_3=0, index_5=0。值设为val_2=2, val_3=3, val_5=5。设存储ugly的数组为arr。
1*2 2*2 3*2 4*2 5*2 6*2 8*2 9*2 10*2 12*2 15*2...
1*3 2*3 3*3 4*3 5*3 6*3 8*3 8*3 10*3 12*3 15*3...
1*5 2*5 3*5 4*5 5*5 6*5 8*5 8*5 10*5 12*5 15*5...
Iteration 1
arr: 1
arr[1]=(val_2 = 2) < (val_3 = 3) < (val_5 = 5)
index_2=1, index_3=0, index_5=0;
val_2=2*arr[index_2]=2*2=4;
arr: 1, 2
Iteration 2
arr[2]=(val_3 = 3) < (val_2 = 4) < (val_5 = 5)
index_2=1, index_3=1, index_5=0;
val_3=3*arr[index_3]=6;
arr:1, 2, 3
Iteration 3
arr[3]=(val_2 = 4) < (val_3 = 6) < (val_5 = 5)
index_2=2, index_3=1, index_5=0;
val_2=2*arr[index2]=6;
arr:1, 2, 3, 4
Iteration 4
arr[4]=(val_5 = 5)<(val_2 = 6)=(val_3 = 6)
index_2=2,index_3=1, index_5=1;
val_5=5*arr[index_5]=10;
arr:1, 2, 3, 4, 5
int minimal(int a, int b, int c){
return (a<b?a:b)<c?(a<b?a:b):c;
}
int nthUglyNumber(int n) {
int* arr=(int*)malloc(sizeof(int)*n);
int index_2=0,index_3=0,index_5=0;
int val_2=2, val_3=3, val_5=5;
arr[0]=1;
for(int i=1;i<n;i++){
arr[i]=minimal(val_2,val_3,val_5);
if(arr[i]==val_2) val_2=arr[++index_2]*2;
if(arr[i]==val_3) val_3=arr[++index_3]*3;
if(arr[i]==val_5) val_5=arr[++index_5]*5;
}
return arr[n-1];
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/senliuy/article/details/47779317