Java中使用优先级队列的第k个最小数的时间复杂度

Java中使用优先级队列的第k个最小数的时间复杂度,java,algorithm,collections,time-complexity,priority-queue,Java,Algorithm,Collections,Time Complexity,Priority Queue,我试图解决一个流行的面试问题,在一组不同的整数中找到第k个最小的数。我阅读了一些解决方案,发现堆数据结构非常适合这个问题 因此,我尝试使用Collections框架的PriorityQueue类实现一个解决方案,假设它在功能上与堆相同 以下是我尝试过的代码: public static int getKthMinimum(int[] input, int k){ PriorityQueue<Integer> heap = new PriorityQueue<Intege

我试图解决一个流行的面试问题,在一组不同的整数中找到第k个最小的数。我阅读了一些解决方案,发现堆数据结构非常适合这个问题

因此,我尝试使用Collections框架的
PriorityQueue
类实现一个解决方案,假设它在功能上与堆相同

以下是我尝试过的代码:

public static int getKthMinimum(int[] input, int k){
    PriorityQueue<Integer> heap = new PriorityQueue<Integer>();

    // Total cost of building the heap - O(n) or O(n log n) ?
    for(int num : input){
        heap.add(num);      // Add to heap - O(log n)
    }

    // Total cost of removing k smallest elements - O(k log n) < O(n) ?
    while(k > 0){
        heap.poll();        // Remove min - O(log n)
        k--;
    }
    return heap.peek();     // Fetch root - O(1) 
}
公共静态int getkthminium(int[]输入,int k){
PriorityQueue heap=new PriorityQueue();
//构建堆的总成本-O(n)还是O(n log n)?
for(int num:input){
add(num);//添加到heap-O(log n)
}
//移除k个最小元素的总成本-O(k logn)0){
poll();//删除min-O(日志n)
k--;
}
返回heap.peek();//获取根-O(1)
}
基于,poll&add方法需要O(logn)时间,peek需要固定时间

  • while
    循环的时间复杂度是多少?(我认为是O(k logn))
  • 就本问题而言,O(k logn)是否应被视为高于O(n)?它在哪里切换有一个阈值吗
  • 这段代码的总时间复杂度是多少?是O(n)吗
  • 如果还没有O(n),在使用PriorityQueue类时,有没有办法在O(n)中解决它
  • 一,。
    while
    循环的时间复杂度是多少?(我认为是O(k logn))

    O(klogn)是正确的

    二,。就本问题而言,O(k logn)是否应被视为高于O(n)?它在哪里切换有一个阈值吗

    你不能这样假设。k可以是0到n之间的任意值−1,这意味着klogn可以是0到nlogn之间的任何位置

    三,。这段代码的总时间复杂度是多少?是O(n)吗

    O(nlogn),因为这是构建堆的成本

    可以在O(n)时间内构建堆,但您的代码不能做到这一点;如果是这样的话,您的总复杂性将是O(n+klogn),或者,等价地,O(MAX(n,klogn))

    四,。如果还没有O(n),在使用PriorityQueue类时,有没有办法在O(n)中解决它

    不,存在最坏情况下的O(n)时间,但它们有点复杂,并且不使用
    PriorityQueue

    基于
    PriorityQueue
    的最快解决方案需要O(MAX(n,nlogMIN)(k,n−k) )时间。(关键是在迭代时只保留堆中最小的k个元素,或者n个元素)−k最大的元素,如果k足够大,那么使用max堆