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
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.
void CheckNode(Node node,int k, int x, ref int counter)
{
if (node.value > x)
{
counter++;
if (counter >= k)
return;
CheckNode(node.Left, k, x, ref counter);
CheckNode(node.Right,k, x, ref counter);
}
}
use it:
counter = 0;
CheckNode(root,index,val,counter );
if (counter >= index)
return true;
return false;
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.
The number of nodes visited with values greater than x will be at most k. Each node visited with value less than x must be a child of a visited node with value greater than x. However, because every node visited except the root must have a parent with value greater than x, the number of nodes of value less than x visited must be at most ((k-1)*2)-(k-1) = k-1, since k-1 of the (k-1)*2 children have values greater than x. This means that we visit k nodes greater than x and k-1 less than x, which is 2k-1.
node.left
may be both less and greater than node.right
. There's a picture of binary heap. –
Potts x
). Your algorithm will declare 19 second greatest value, 17 - third, 2 - forth, 7 - fifth and so on. But we all know it's not so. –
Potts x
there is no need to find Kth largest element, In the case which is just smaller than Kth largest element, you know all Parents (in the path from root to Kth largest element) are bigger than this, So maximum height of tree upto Kth Largest element is K
, Also you just check child if parent bigger than x(at most K time) so you didn't check more than 3*k node till reaching to Kth largest element. –
Namangan return
at counter >=k
rather than counter ==k
? –
Monthly 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));
}
}
© 2022 - 2024 — McMap. All rights reserved.