[M思维] lc313. 超级丑数(多路归并+STL堆)
Posted Ypuyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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;
}
};
以上是关于[M思维] lc313. 超级丑数(多路归并+STL堆)的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 313. 超级丑数(最小堆动态规划)/413. 等差数列划分/167. 两数之和 II - 输入有序数组