题目描述:
我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。
示例:
输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。
说明:1 是丑数。
n 不超过1690。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/chou-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
分析:
这道题我之所以能自己写出来,貌似是因为我见过,好像是在洛谷还是蓝桥杯来着。。。。
不过问题不大,能不看题解写出来就是好的。思路如下:
1.维护三个队列,q2,q3,q5。q2中的元素依次与2相乘,q3中的元素依次与3相乘,q5中的元素依次与5相乘。
2.首先,数组1依次进入队列q2,q3,q5。
3.q2,q3,q5三个队列的首元素分别与2,3,5相乘,得到temp2,temp3,temp5。
4.比较temp2,temp3,temp5三者大小,选出最小的那个,记为temp,temp就是下一个丑数
5.将temp加入丑数数组的下一位,并且从相应的队列中删除对应首元素(例如,temp是队列q2的首元素*2得到的,那么就删除q2的首元素),然后把temp依次加入到队列q2,q3,q5的末尾。
6.返回第3步,进行循环,直到找到第n位丑数
代码如下:
class Solution {
public:
int nthUglyNumber(int n) {
vector<unsigned long long int> res;
// 第0位没有用,随便给了个数
res.push_back(0);
// 第一位是1
res.push_back(1);
// 维护三个队列
queue<unsigned long long int> q2;
queue<unsigned long long int> q3;
queue<unsigned long long int> q5;
// 1添加至三个队列尾部
q2.push(1);
q3.push(1);
q5.push(1);
// 找完1690个丑数
for(int i=1;i<=1690;i++)
{
// 三个队列的首元素依次与2、3、5相乘,保存在temp2,temp3,temp5中
unsigned long long int temp2,temp3,temp5;
if(!q2.empty())
temp2=2*q2.front();
if(!q3.empty())
temp3=3*q3.front();
if(!q5.empty())
temp5=5*q5.front();
// 计算最小值,赋给temp
unsigned long long int temp=(temp2>temp3)?(temp3>temp5?temp5:temp3):(temp2>temp5?temp5:temp2);
// 看看temp究竟是谁计算出来的,删除那个队列的首元素
if(temp==temp2) q2.pop();
if(temp==temp3) q3.pop();
if(temp==temp5) q5.pop();
// temp就是下一个丑数,加入丑数数组中
res.push_back(temp);
// temp依次添加到三个队列尾部
q2.push(temp);
q3.push(temp);
q5.push(temp);
}
// 返回要计算的结果
return res[n];
}
};
看了下题解,跟这个思路差不多,就不再写题解的思路了。