我正在实现一个同时具有popMin和popMax方法的队列类。到目前为止,我已经使用了两个优先级队列,但即使删除是log(n)时间,我也必须从其他队列中删除,这是线性的。我知道可以使用二进制堆实现双端优先级队列,但是如果我没弄错的话需要线性时间来构建?有没有办法可以更有效地做到这一点?我也只能使用Java库类。
static class MinMaxQueue {
PriorityQueue<String> MinQueue = new PriorityQueue<String>();
PriorityQueue<String> MaxQueue = new PriorityQueue<String>(Collections.reverseOrder());
void push(String val) {
MinQueue.add(val);
MaxQueue.add(val);
}
String popMin() {
MaxQueue.remove(MinQueue.peek());
return MinQueue.remove();
}
String popMax() {
MinQueue.remove(MaxQueue.peek());
return MaxQueue.remove();
}
int size() {
return MinQueue.size();
}
}
答案 0 :(得分:3)
min-max heap支持O(1)find-min / max和O(log n)delete-min / max。 Guava的MinMaxPriorityQueue是min-max堆的实现。
java标准库中没有min-max堆实现。如果您不能使用第三方库,并且您不想实现自己的最小 - 最大堆。您可以尝试基于红黑树实施的TreeSet。它有O(logn)delete-min / max,权衡是find-min / max也是O(logn)。您可以尝试使其threaded跟踪最小值/最大值,但需要对 TreeSet 进行大量更改。
如果您坚持使用两个 PriorityQueues 来实现最小 - 最大队列。您可以将另一个队列的所有元素索引跟踪到HashMap中,如the answer。因为PriorityQueue #removeAt(index)是O(logn)。但是每个元素移动都需要更新HashMap。我强烈建议不要这样做,因为额外的空间使用和可能性能不佳。