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, and n does not exceed 1690.
这道题的题意就是查找第n个丑陋数是多少,丑陋数一定是正数,且它的因子只由2,3,5组成,其中规定第一个丑陋数是1。
可以用动态规划的思想来解此题,我们将所有的丑陋数分到三个列表里面(通过一个丑陋数乘以2得到/通过一个丑陋数乘以3得到/个丑陋数乘以5得到),我们每次取丑陋数都是取当前三个列表的未被取过的最小的丑陋数。
详细的解释即为首先在2,3,5中取得第二个丑陋数2,乘以2的表更新到2乘以2即为4(第二个丑陋数2乘以2)。下次就是3,4,5里面取最小的,取了3之后乘以3的表更新为6(第二个丑陋数2乘以3)。之后4,5,6里面取了4,第一个表最新值变为6(第三个丑陋数3乘以2)以此类推可以求出3个列表以及第n个丑陋数位多少。还要说明的是每个表都有自己的进度,即一个表每次被取到丑陋数以后,被乘数就会变成现在作为被乘数的丑陋数的下一个丑陋数。
代码如下:
class Solution {
public:
int nthUglyNumber(int n) {
if(n == 1) return 1;
int dp[1961];
memset(dp, 0, sizeof(dp));
int index2 = 0, index3 = 0, index5 = 0;
int val_2 = 2, val_3 = 3, val_5 = 5;
int i = 1;
dp[0] = 1;
for(i = 1; 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[index2] * 2;}
if(val == val_3) {dp[i] = val_3; index_3++; val_3 = dp[index3] * 3;}
if(val == val_5) {dp[i] = val_5; index_5++; val_5 = dp[index5] * 5;}
}
return dp[n - 1];
}
};