[M思维] lc313. 超级丑数(多路归并+STL堆)

1. 题目来源

链接:313. 超级丑数

前置知识:[M思维] lc264. 丑数 II(多路归并+STL堆)

2. 题目解析

是一道非常经典题目的升级版,[M思维] lc264. 丑数 II(多路归并+STL堆)。但换汤不换药,也依旧采用多路归并的思想,但显然没发用指针来维护,那就用堆来维护就可以了。

方法一:STL堆+多路归并

class Solution {
public:
    int nthSuperUglyNumber(int n, vector<int>& primes) {
        typedef pair<int, int> PII;
        priority_queue<PII, vector<PII>, greater<PII>> heap;
        for (int x: primes) heap.push({x, 0});		// 指针*对应质数,指针的下标
        vector<int> q(n);							// 存储超级丑数
        q[0] = 1;									// 将1放入超级丑数,下标为0
        for (int i = 1; i < n;) {
            auto t = heap.top(); heap.pop();		// 找到最小的超级丑数
            if (t.first != q[i - 1]) q[i ++ ] = t.first;	// 如果不和前一个值相同,即不重复,则为新的超级丑数
            // 指针移动,得到对应的质数p,超级丑数指针下标idx,指针向后走一位。即
            int idx = t.second, p = t.first / q[idx];	
            heap.push({p * q[idx + 1], idx + 1});	// 指针向后移动一位,乘以对应的质数
        }
        return q[n - 1];
    }
};

方法二:STL堆+通用方法

class Solution {
public:
    int nthSuperUglyNumber(int n, vector<int>& primes) {
        typedef long long LL;
        unordered_set<LL> S;
        priority_queue<LL, vector<LL>, greater<LL>> Q;
        Q.push(1); S.insert(1);

        LL res = 0;
        for (int i = 0; i < n; i ++ ) {
            LL cur = Q.top(); Q.pop();
            res = cur;
            for (int j = 0; j < primes.size(); j ++ ) {
                LL t = cur * primes[j];
                if (!S.count(t)) {
                    S.insert(t);
                    Q.push(t);
                }
            }
        }

        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值