剑指 Offer 49. 丑数

题目链接: leetcode.

这道题都做过一遍了喂(#`O′)竟然还是不会!

用堆,每次弹出堆顶的数, 将其分别乘以2,3,5压入堆
为了避免重复,使用哈希表存放已经生成的数

如果存int,在输入1690时溢出:
runtime error: signed integer overflow: 429981696 * 5 cannot be represented in type 'int'

/*
执行用时:160 ms, 在所有 C++ 提交中击败了9.06%的用户
内存消耗:33.5 MB, 在所有 C++ 提交中击败了5.04%的用户
*/
class Solution {
public:
    int nthUglyNumber(int n) {
        priority_queue<long, vector<long>, greater<long> > Q;
        //priority_queue默认返回的是最大的 ,所以要加 greater<>
		Q.push(1);
		vector<int> ans;
		unordered_set<long> S;
		S.insert(1);
		for(int i = 0;i < n;++i)
		{
			long t = Q.top();
			ans.push_back(t);
			Q.pop();
			if(!S.count(t * 2))
			{
				S.insert(t * 2);
				Q.push(t * 2);
			}
			if(!S.count(t * 3))
			{
				S.insert(t * 3);
				Q.push(t * 3);
			}
			if(!S.count(t * 5))
			{
				S.insert(t * 5);
				Q.push(t * 5);
			}
		} 
		return ans[n - 1];
    }
};

使用动态规划的思想,用三个指针p2,p3,p5分别指向下一个应该乘的数
比较num[p2]*2,num[p3]*3num[p5]*5哪一个更小,便添加到数组后
将乘过的指针后移一位
(注意,每个与添加的数相等对应的指针都要移动,比如添加6,p2:3->4;p3:2->3)

/*
执行用时:8 ms, 在所有 C++ 提交中击败了83.57%的用户
内存消耗:7.4 MB, 在所有 C++ 提交中击败了79.94%的用户
*/
class Solution {
public:
    int nthUglyNumber(int n) {
    	vector<int> num(n);
		num[0] = 1;
		int p2 = 0, p3 = 0, p5 = 0;
		int i = 1;
		while(i < n)
		{
			int t = num[p2] * 2;
			t = min(t, num[p3] * 3);
			t = min(t, num[p5] * 5);
			num[i] = t;
			i++;
			if(num[p2] * 2 == t)
				p2++;
			if(num[p3] * 3 == t)
				p3++;
			if(num[p5] * 5 == t)
				p5++;
		} 
		return num[n - 1];
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值