代码之家  ›  专栏  ›  技术社区  ›  Elimination

按键在priorityqueue中查找元素

  •  2
  • Elimination  · 技术社区  · 7 年前

    假设有人给了我钥匙。我想在优先级队列中找到一个元素,它的键等于或大于给定的键。

    很明显,我想在 O(logn) . 我几乎肯定Java提供了这样的方法,但是找不到它(在官方文档中查看)

    3 回复  |  直到 7 年前
        1
  •  3
  •   Kaidul    7 年前

    没有这种方法。

    优先级队列的底层实现是最小堆(它也可以配置为充当最小堆)。所以对于具有max heap属性的优先级队列,当您检查peek元素(即 O(1) 操作),它将返回最大元素。轮询后,将执行heapify,下一个顶级元素将是第二个最大值。这种治疗 O(logn) 复杂性。因此,如果您想获得大于或等于给定键的所有键,则需要从最大堆优先级队列一直进行轮询,直到顶级元素小于给定键。最坏的情况是 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;
    }
    
        2
  •  1
  •   amrender singh    7 年前

    java优先级队列 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);
    
        3
  •  1
  •   Jim Mischel    7 年前

    有一种非破坏性的方法。您可以使用 iterator 搜索。

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

    其复杂性显然是o(n)。公认答案中描述的破坏性技术的复杂性为o(k log n),其中 k 是小于您正在搜索的项目数。在最坏的情况下, k=n ,算法为o(n logn)。