按键在PriorityQueue中查找元素

时间:2018-06-14 14:50:28

标签: java data-structures priority-queue

假设我已获得一些关键。我想要找到的是优先级队列中的一个元素,使得它的键等于或大于给定的键。

显然,我希望在O(logn)中完成。我几乎可以肯定Java提供了这样的方法但却找不到它(在官方文档中查看)

3 个答案:

答案 0 :(得分:3)

没有这样的方法。

优先级队列的底层实现是min heap(它也可以配置为充当min heap)。因此,对于具有最大堆属性的优先级队列,当您检查peek元素(即O(1)操作)时,它将返回最大元素。轮询后,将执行堆化,下一个顶部元素将是第二个最大值。 O(logn)复杂性的这种堆积。因此,如果要获得大于或等于给定键的所有键,则需要从最大堆优先级队列开始轮询,直到top元素小于给定键。在最坏的情况下,这可以是O(nlogn)

同样在这些操作之后,队列结构将被更改,因为一些键已被轮询。因此,在下一次操作之前,您必须通过重新推送轮询密钥来恢复队列的状态,这些密钥也将是O(nlogn)

PriorityQueue<Integer> queue = new PriorityQueue<>(10, Collections.reverseOrder())

List<Integer> keysGreaterOrEqualTo(Integer key) {
    List<Integer> keys = new ArrayList<>();
    while(!queue.isEmpty() && queue.peek() >= key) {
        keys.add(queue.poll());
    }
    return keys;
}

答案 1 :(得分:1)

Java Priority Queue具有contains()方法,如果在优先级队列中找到密钥,则返回true。 参考 - Reference

要查找大于或等于的密钥,您可以实现自己的自定义方法。如:

int searchkey = 5, foundKey = 0;

While(!pq.isEmpty()){
  foundKey = pq.poll();   
  if(foundKey == searchKey || foundKey > searchKey)
    break;
}
System.out.println(foundKey == searchKey || foundKey > searchKey ? foundKey : -1);

答案 2 :(得分:0)

有一种非破坏性的方法。您可以使用iterator进行搜索,而不是在找到符合条件的内容之前从队列中删除内容。

理解迭代器不会以任何特定顺序返回项目,因此如果您希望最小项目大于或等于某个值,您仍然需要遍历整个集合。

这种复杂性显然是O(n)。在接受的答案中描述的破坏性技术的复杂性是O(k log n),其中k是小于您正在搜索的项目的数量。在最坏的情况下,k=n,算法是O(n log n)。