题目地址:
https://leetcode.com/problems/number-of-orders-in-the-backlog/description/
给定若干的下单,每个下单包含价格、股数和下单是买还是卖, 1 1 1是买, 0 0 0是卖。每个单下了以后,如果其是买单,则其会按照价格优先的方式满足价格低于或等于买单价格,然后撮合交易。如果是卖单则类似。问最后还有多少股数没有被交易完。答案模 1 0 9 + 7 10^9+7 109+7后返回。
可以开两个堆,分别存买单和卖单,按价格优先排序,买单的堆顶是最大买价,卖单的堆顶是最小卖价,这样一旦来了一个单子,就可以看堆顶是否能撮合交易。代码如下:
class Solution {
public:
using PII = pair<int, int>;
#define x first
#define y second
int getNumberOfBacklogOrders(vector<vector<int>> &orders) {
static const int MOD = 1e9 + 7;
priority_queue<PII> buys;
priority_queue<PII, vector<PII>, greater<>> sells;
for (auto &o : orders) {
if (!o[2]) {
while (sells.size() && sells.top().x <= o[0]) {
auto p = sells.top();
sells.pop();
int cnt = min(p.y, o[1]);
p.y -= cnt;
o[1] -= cnt;
if (p.y) {
sells.push(p);
break;
}
}
if (!o[1]) continue;
if (buys.size() && buys.top().x == o[0]) {
auto p = buys.top();
buys.pop();
p.y += o[1];
buys.push(p);
} else
buys.emplace(o[0], o[1]);
} else {
while (buys.size() && buys.top().x >= o[0]) {
auto p = buys.top();
buys.pop();
int cnt = min(p.y, o[1]);
p.y -= cnt;
o[1] -= cnt;
if (p.y) {
buys.push(p);
break;
}
}
if (!o[1]) continue;
if (sells.size() && sells.top().x == o[0]) {
auto p = sells.top();
sells.pop();
p.y += o[1];
sells.push(p);
} else
sells.emplace(o[0], o[1]);
}
}
int res = 0;
for (; buys.size(); buys.pop()) res = (res + buys.top().y) % MOD;
for (; sells.size(); sells.pop()) res = (res + sells.top().y) % MOD;
return res;
}
};
时间复杂度 O ( n log n ) O(n\log n) O(nlogn),空间 O ( n ) O(n) O(n)。