题目:
编写一个程序,找出第 n 个丑数。
丑数就是质因数只包含 2, 3, 5 的正整数。
题解:
方法一:
符合条件的数需从小到大记录下来,优先队列具备这样的性质,因而对队列的top,将它取出,将2top,3top,5*top压入队列,当取出第n个top时,将他return。
typedef long long ll;
class Solution {
public:
int nthUglyNumber(int n) {
priority_queue<ll,vector<ll>, greater<ll> > pq;
ll now=1;
for(int i=1;i<n;i++)
{
pq.push(2*now);
pq.push(3*now);
pq.push(5*now);
now=pq.top();
pq.pop();
while(pq.top()==now) pq.pop();
}
return int(now);
}
};
方法二:
方法一时间复杂度是不够好的,主要在于for循环中多个push操作与去重操作,浪费了大量时间,动态规划则尽可能将重复元素不进行记录,每次只记录最小的那个数,省去大量去重和压入操作,得到较好的时间复杂度。
typedef long long ll;
class Solution {
public:
int nthUglyNumber(int n) {
vector<int> dp(n);
dp[0]=1;
int dp2,dp3,dp5;
dp2=dp3=dp5=0;
for(int i=1;i<n;i++)
{
dp[i]=min(dp[dp2]*2,min(dp[dp3]*3,dp[dp5]*5));
if(dp[i]==dp[dp2]*2) dp2++;
if(dp[i]==dp[dp3]*3) dp3++;
if(dp[i]==dp[dp5]*5) dp5++;
}
return dp[n-1];
}
};