class Solution {
public:
int nthUglyNumber(int n) {
// dp[i] is the nth ugly number
int *dp = new int[n];
int prev[3] = {0};
// begin dp
dp[0] = 1;
for (int i = 1; i < n; i++) {
int min = std::min(std::min(dp[prev[0]]*2, dp[prev[1]]*3), dp[prev[2]]*5);
if (dp[prev[0]]*2 == min) prev[0]++;
if (dp[prev[1]]*3 == min) prev[1]++;
if (dp[prev[2]]*5 == min) prev[2]++;
dp[i] = min;
}
return dp[n - 1];
}
};
共以下 13 个回答
class Solution {
public int nthUglyNumber(int n) {
int[] dp = new int[n];
dp[0] = 1;
int a=0,b=0,c=0;
for(int i=1;i<n;i++){
dp[i] = Math.min(Math.min(dp[a]2,dp[b]3),dp[c]5);
if(dp[i]dp[a]2)a++;
if(dp[i]dp[b]3)b++;
if(dp[i]dp[c]5)c++;
}
return dp[n-1];
}
}
时间空间均是o(n)
“`java
class Solution {
public int nthUglyNumber(int n) {
//动态规划
//dp[i]为第i个丑数,则dp[n]即为所求
//dp[1] = 1
//设置三个指针,分别对应2,3,5 ,p2,p3,p5
//i >= 2时,dp[i] = Min(dp[p2]*2,dp[p3]*3,dp[p5]*5)
//判断dp[i]与哪个相等,则对应的指针需要加1
int[] dp = new int[n + 1];
dp[1] = 1;
int p2 = 1,p3=1,p5=1;
for (int i = 2; i <= n; i++) { int p2p = dp[p2]*2; int p3p = dp[p3]*3; int p5p = dp[p5]*5; dp[i] = Math.min(Math.min(p2p, p3p),p5p); if (dp[i] == p2p) { p2++; } if (dp[i] == p3p) { p3++; } if (dp[i] == p5p) { p5++; } } return dp[n]; } }
时间复杂度:O(n)
空间复杂度:O(n)
MY动态规划
【思路】DP,dp[i]为第i个丑数
【复杂度】时间O(n),空间O(n)
时间复杂度O(n)
时间复杂度O(n)
假设三个数组的指针分别是i,j,k,此时均是指向第一个元素,然后比较A[i],B[j]和C[k],得到的最小的数A[i],就是ugly[1],此时ugly就变成{1,2}了,对应的ABC数组就分别变成了:
A : {12,22……}
B : {13, 23……}
C :{15,25……}
此时根据合并有序数组的原理,A数组指针i就指向了下一个元素,即’2*2’,而j和k依然分别指向B[0]和C[0],然后进行下一轮合并,就是A[1]和B[0]和C[0]比较,最小值作为ugly[2]…..如此循环n次,就可以得到ugly[n]了。
此外,注意到ABC三个数组实际上就是ugly[]2,ugly[]3和ugly[]5的结果,所以每次只需要比较A[i]=ugly[i]2,B[j]=ugly[j]3和C[k]=ugly[k]5的大小即可。然后谁最小,就把对应的指针往后移动一个,为了去重,如果多个元素都是最小,那么这多个指针都要往后移动一个。
动态规划
时间:O(n)
空间:O(n)
“`C++ uglyNums; // 存储丑数的数组
int getNthUglyNumber(int n) {
vector
uglyNums.push_back(1); // 第一个丑数是1
}
“`