Consider a binary heap containing n numbers (the root stores the greatest number). You are given a positive integer k < n and a number x. You have to determine whether the kth largest element of the heap is greater than x or not. Your algorithm must take O(k) time. You may use O(k) extra storage
how to determine if the kth largest element of the heap is greater than x
18.9k Views Asked by Prajapat At
2
There are 2 best solutions below
0

public class KSmallest2 {
private MinPQ<Integer> minHeap;
private int x;
private int k;
private int count = 0;
public KSmallest2(String filename, int x, int k) {
this.x = x;
this.k = k;
minHeap = new MinPQ<>();
try {
Scanner in = new Scanner(new File(filename));
while (in.hasNext()) {
minHeap.insert(in.nextInt());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public boolean check(int index) {
if (index > minHeap.size()) {
return false;
}
if (minHeap.getByIndex(index) < x) {
count++;
if (count >= k) {
return true;
}
return check(2 * index) ||
check(2 * index + 1);
}
return false;
}
public static void main(String[] args) {
KSmallest2 ks = new KSmallest2("src/main/resources/minheap.txt", 18, 5);
System.out.println(ks.minHeap);
System.out.println(ks.check(1));
}
}
Simple dfs can do the job. We have a counter set to zero. Start from the root and in each iteration check the value of current node; if it is greater than x, then increase the counter and continue the algorithm for one of the child nodes. The algorithm terminates if counter is bigger than equal k or if there is no node left to check. The running time is O(k) because at most k node will be iterated and each iteration is in O(1).
A pseudo-code looks like as follows.
use it:
if node.value < x then all children values are smaller than x and there is no need to check.
As @Eric Mickelsen mentioned in comments worst case running time is exactly 2k-1 (k>0) as follows.