Write a program to find the n
-th ugly number.
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.
本来的解法超时了,引用他人的思路:
找出第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...
class Solution {
public:
int nthUglyNumber(int n) {
vector<int> res;
res.push_back(1);
int ind_2=0;
int ind_3=0;
int ind_5=0;
int min_2=2;
int min_3=3;
int min_5=5;
for (int i=1;i<n;i++){
int min_v;
if (min_2<min_3)
min_v=min(min_2,min_5);
else
min_v=min(min_3,min_5);
res.push_back(min_v);
if (min_v==min_2) { ind_2++; min_2=res[ind_2]*2;}
if (min_v==min_3) { ind_3++; min_3=res[ind_3]*3;}
if (min_v==min_5) { ind_5++; min_5=res[ind_5]*5;}
}
return res[n-1];
}
};