题目链接:leetcode264
思路:
- 堆
每次把当前最小的丑数能递推到的丑数push进小根堆中,根据小根堆的性质每次pop一定是当前最小的丑数,复杂度 O ( n l o g n ) O(nlogn) O(nlogn)
- 动态规划
所有丑数的全集一定由2,3,5的倍数组成的集合以及1构成
由于要按顺序输出丑数,即丑数集合要具有单调性
枚举每个数字的倍数,显然一个数字的倍数集合单调递增
维护三个指针每次选最小的数加入丑数集即可
由于一个丑数可能同时存在于两个倍数集中,如 6 = 2 ∗ 3 = 3 ∗ 2 6=2*3=3*2 6=2∗3=3∗2
所以每当找到一个当前最小的丑数,要让所以等于这个丑数的指针++
复杂度 O ( n ) O(n) O(n)
class Solution {
public:
int nthUglyNumber(int n) {
vector<int> dp(n+1);
dp[1]=1;
int p2=1,p3=1,p5=1;
for(int i=2; i<=n; i++) { //找一个长度为n且单调递增的丑数序列
int cur=min(dp[p2]*2, min(dp[p3]*3, dp[p5]*5));
if(cur == dp[p2]*2) p2++;
if(cur == dp[p3]*3) p3++;
if(cur == dp[p5]*5) p5++;
dp[i]=cur;
}
return dp[n];
}
};