题目:
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.
思路:
我们知道丑数是由某个丑数乘上2或者3或者5得来。而且初始化时第一个丑数是1。
- 我们将已经按顺序求得的丑数放在数组中,该数组初始化时就只有一个1。
- 接下来考虑将已经求得的数组中的某个元素乘上2或者3或者5得到下一个应该存入数组的丑数。
- 比如当前的丑数数组中最大的值是M,那么下一个丑数应该是比M大的丑数。挑一个丑数乘上2,挑一个丑数乘上3,挑一个丑数乘上5,这三个结果都需要大于M。所以乘上2的那个丑数需要大于M/2,而乘上3的那个丑数需要大于M/3,乘上5的那个丑数应该大于M/5。
- 我们使用一个数组保存2,3,5接下来乘的那个丑数的下标,使得结果都大于M。
- 这个丑数的下标什么时候用来更新呢?初始化时下标都为0,因为这个时候丑数数组中只有一个元素1。当将M加入到数组后,把2,3,5对应的下标各自往后移动,使得乘的结果大于M。
class Solution {
public:
int nthUglyNumber(int n) {
vector<int> dp(n);
int index_2 = 0, index_3 = 0, index_5 = 0;
int val_2 = 2, val_3 = 3, val_5 = 5;
int i = 1;
dp[0] = 1;
for(;i < n;i++){
int val = min(val_2, min(val_3, val_5) );
if(val == val_2) {dp[i] = val_2; index_2++; val_2 = dp[index_2] * 2;}
if(val == val_3) {dp[i] = val_3; index_3++; val_3 = dp[index_3] * 3;}
if(val == val_5) {dp[i] = val_5; index_5++; val_5 = dp[index_5] * 5;}
}
return dp[n - 1];
}
};