知识点
堆 多路归并
思路
如果直接维护一个堆来维护最大的k组数对,遍历每一对数,时间复杂度是,显然超时,不做讨论。
我们考虑把每个priceA的位置当做一个组,然后每个组的起点位于priceB的末尾,建立一个堆选出那个组是最大的。
首先我们把每个priceA的位置和priceB的末尾元素组成的组入堆。之后每次选出当前的最大元素后,我们看这一组是不是后继有人(意思是能不能把该组对应的priceB的指针往前走),如有把该候选数对入堆。因为每次出堆一个,入堆最多一个,堆的大小最多也就和priceA的大小一样。
时间复杂度为
AC Code(C++)
#include <queue>
#define x first
#define y second
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pricesA int整型vector
* @param pricesB int整型vector
* @param k int整型
* @return int整型vector<vector<>>
*/
using pii = pair<int, int>;
vector<vector<int> > kPairsWithLargestSums(vector<int>& pricesA, vector<int>& pricesB, int k) {
int n = pricesA.size(), m = pricesB.size();
auto cmp = [&](pii& a, pii& b) {
if (pricesA[a.x] + pricesB[a.y] == pricesA[b.x] + pricesB[b.y]) return pricesA[a.x] < pricesA[b.x];
return pricesA[a.x] + pricesB[a.y] < pricesA[b.x] + pricesB[b.y];
};
priority_queue<pii, vector<pii>, decltype(cmp)> q(cmp);
vector<vector<int>> res;
for (int i = 0; i < n; i ++) {
q.emplace(i, m - 1);
}
while (k --) {
auto [x, y] = q.top();
q.pop();
res.push_back({pricesA[x], pricesB[y]});
if (y > 0) q.emplace(x, y - 1);
}
return res;
}
};

京公网安备 11010502036488号