简体   繁体   中英

Time complexity of k-th smallest number using PriorityQueue in Java

I am trying to solve the popular interview question Find the k-th smallest number in an array of distinct integers . I read some solutions and found that a heap data structure suits this problem very well.

So, I have tried to implement a solution using the PriorityQueue class of the Collections framework, assuming that it is functionally identical to a heap.

Here is the code that I've tried:

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) 
}

Based on the docs , the poll & add methods take O(log n) time and peek takes constant time.

  1. What will be the time complexity of the while loop? (I think O(k log n)).
  2. Should O(k log n) be considered higher than O(n) for the purpose of this question? Is there a threshold where it switches?
  3. What will be the total time complexity of this code? Will it be O(n)?
  4. If not already O(n), is there a way to solve it in O(n), while using the PriorityQueue class?

1. What will be the time complexity of the while loop? (I think O(k log n)).

O ( k log n ) is correct.

2. Should O(k log n) be considered higher than O(n) for the purpose of this question? Is there a threshold where it switches?

You cannot assume that. k can be anywhere from 0 to n −1, which means that k log n can be anywhere from 0 to n log n .

3. What will be the total time complexity of this code? Will it be O(n)?

O ( n log n ), because that's the cost of building the heap.

It's possible to build a heap in O ( n ) time, but your code doesn't do that; if it did, your total complexity would be O ( n + k log n ) or, equivalently, O (MAX( n , k log n )).

4. If not already O(n), is there a way to solve it in O(n), while using the PriorityQueue class?

No. There exist selection algorithms in worst-case O ( n ) time, but they're a bit complicated, and they don't use PriorityQueue .

The fastest PriorityQueue -based solutions would require O (MAX( n , n log MIN( k , nk ))) time. (The key is to keep only the k smallest elements in the heap while iterating — or the nk largest elements and use a max-heap, if k is large enough for that to be worthwhile.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM