264. 丑数 II
编写一个程序,找出第 n 个丑数。
丑数就是只包含质因数 2, 3, 5 的正整数。
示例:
输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。
说明:
1 是丑数。
n 不超过1690。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ugly-number-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法1:优先队列
int不够存,要longlong来存;
最小堆的优先队列初始化:
priority_queue<int,vector<int>,greater<in>> q;
注意点:
去重:2的倍数不添加3和5的公倍数,3的倍数不添加5的公倍数,完成去重;
去重也可用哈希map或set保存,完成去重。
class Solution {
public:
int nthUglyNumber(int n) {
q.push(1);
long long res;
while(n>0)
{
res=q.top();
//cout<<res<<endl;
if((res*2)%3!=0&&(res*2)%5!=0)
q.push(res*2);
if((res*3)%5!=0)
q.push(res*3);
q.push(res*5);
q.pop();
n--;
}
return int(res);
}
private:
priority_queue<long long,vector<long long>,greater<long long>> q;
};
解法2
三指针动态规划;
三个指针表示*2,*3,*5,同时指向数组里的1;
每次取三个指针乘以各自倍数的最小值入数组,该指针后移,若有其他指针也相同,一样后移,执行n-1次,即可找到第n个丑数;
class Solution {
public:
int nthUglyNumber(int n) {
vector<int> res;
res.push_back(1);
int i,j,k;
i=j=k=0;
int ugly;
for(int t=1;t<n;t++) //n-1次循环
{
ugly=findmin(res[i]*2,res[j]*3,res[k]*5);
res.push_back(ugly);
if(ugly==res[i]*2) i++;
if(ugly==res[j]*3) j++;
if(ugly==res[k]*5) k++;
}
return res[n-1];
}
private:
int findmin(int a,int b, int c)
{
int res;
if(a<b) res=a;
else res=b;
if(c<res) res=c;
return res;
}
};
注意点
min(int a, int b, int c)可以写成 min(min(int a, int b), int c);