K'th largest element in a stream - GeeksforGeeks

22 Feb, 2022
Given an infinite stream of integers, find the k’th largest element at any point of time.Example: 
Input:
stream[] = {10, 20, 11, 70, 50, 40, 100, 5, ...}
k = 3

Output:    {_,   _, 10, 11, 20, 40, 50,  50, ...}
Extra space allowed is O(k). 
We have discussed different approaches to find k’th largest element in an array in the following posts. K’th Smallest/Largest Element in Unsorted Array | Set 1 K’th Smallest/Largest Element in Unsorted Array | Set 2 (Expected Linear Time)K’th Smallest/Largest Element in Unsorted Array | Set 3 (Worst Case Linear Time)Here we have a stream instead of whole array and we are allowed to store only k elements.
A Simple Solution is to keep an array of size k. The idea is to keep the array sorted so that the k’th largest element can be found in O(1) time (we just need to return first element of array if array is sorted in increasing order) How to process a new element of stream? For every new element in stream, check if the new element is smaller than current k’th largest element. If yes, then ignore it. If no, then remove the smallest element from array and insert new element in sorted order. Time complexity of processing a new element is O(k).
A Better Solution is to use a Self Balancing Binary Search Tree of size k. The k’th largest element can be found in O(Logk) time. How to process a new element of stream? For every new element in stream, check if the new element is smaller than current k’th largest element. If yes, then ignore it. If no, then remove the smallest element from the tree and insert new element. Time complexity of processing a new element is O(Logk).
An Efficient Solution is to use Min Heap of size k to store k largest elements of stream. The k’th largest element is always at root and can be found in O(1) time. How to process a new element of stream? Compare the new element with root of heap. If new element is smaller, then ignore it. Otherwise replace root with new element and call heapify for the root of modified heap. Time complexity of finding the k’th largest element is O(Logk). 
CPP
Java
C#
// A C++ program to find k'th// smallest element in a stream#include <climits>#include <iostream>using namespace std; // Prototype of a utility function// to swap two integersvoid swap(int* x, int* y); // A class for Min Heapclass MinHeap {    int* harr; // pointer to array of elements in heap    int capacity; // maximum possible size of min heap    int heap_size; // Current number of elements in min heappublic:    MinHeap(int a[], int size); // Constructor    void buildHeap();    void MinHeapify(        int i); // To minheapify subtree rooted with index i    int parent(int i) { return (i - 1) / 2; }    int left(int i) { return (2 * i + 1); }    int right(int i) { return (2 * i + 2); }    int extractMin(); // extracts root (minimum) element    int getMin() { return harr[0]; }     // to replace root with new node x and heapify() new    // root    void replaceMin(int x)    {        harr[0] = x;        MinHeapify(0);    }}; MinHeap::MinHeap(int a[], int size){    heap_size = size;    harr = a; // store address of array} void MinHeap::buildHeap(){    int i = (heap_size - 1) / 2;    while (i >= 0) {        MinHeapify(i);        i--;    }} // Method to remove minimum element// (or root) from min heapint MinHeap::extractMin(){    if (heap_size == 0)        return INT_MAX;     // Store the minimum value.    int root = harr[0];     // If there are more than 1 items,    // move the last item to    // root and call heapify.    if (heap_size > 1) {        harr[0] = harr[heap_size - 1];        MinHeapify(0);    }    heap_size--;     return root;} // A recursive method to heapify a subtree with root at// given index This method assumes that the subtrees are// already heapifiedvoid MinHeap::MinHeapify(int i){    int l = left(i);    int r = right(i);    int smallest = i;    if (l < heap_size && harr[l] < harr[i])        smallest = l;    if (r < heap_size && harr[r] < harr[smallest])        smallest = r;    if (smallest != i) {        swap(&harr[i], &harr[smallest]);        MinHeapify(smallest);    }} // A utility function to swap two elementsvoid swap(int* x, int* y){    int temp = *x;    *x = *y;    *y = temp;} // Function to return k'th largest element from input streamvoid kthLargest(int k){    // count is total no. of elements in stream seen so far    int count = 0, x; // x is for new element     // Create a min heap of size k    int* arr = new int[k];    MinHeap mh(arr, k);     while (1) {        // Take next element from stream        cout << "Enter next element of stream ";        cin >> x;         // Nothing much to do for first k-1 elements        if (count < k - 1) {            arr[count] = x;            count++;        }         else {            // If this is k'th element, then store it            // and build the heap created above            if (count == k - 1) {                arr[count] = x;                mh.buildHeap();            }             else {                // If next element is greater than                // k'th largest, then replace the root                if (x > mh.getMin())                    mh.replaceMin(x); // replaceMin calls                                      // heapify()            }             // Root of heap is k'th largest element            cout << "K'th largest element is "                 << mh.getMin() << endl;            count++;        }    }} // Driver program to test above methodsint main(){    int k = 3;    cout << "K is " << k << endl;    kthLargest(k);    return 0;}
// Java program for the above approachimport java.io.*;import java.util.*; class GFG {     /*  using min heap DS   how data are stored in min Heap DS         1       2   3  if k==3 , then top element of heap  itself the kth largest largest element   */  static PriorityQueue<Integer> min;  static int k;   static List<Integer> getAllKthNumber(int arr[])  {         // list to store kth largest number    List<Integer> list = new ArrayList<>();     // one by one adding values to the min heap    for (int val : arr) {       // if the heap size is less than k , we add to      // the heap      if (min.size() < k)        min.add(val);       /*      otherwise ,      first we  compare the current value with the      min heap TOP value       if TOP val > current element , no need to      remove TOP , bocause it will be the largest kth      element anyhow       else  we need to update the kth largest element      by removing the top lowest element      */       else {        if (val > min.peek()) {          min.poll();          min.add(val);        }      }       // if heap size >=k we add      // kth largest element      // otherwise -1       if (min.size() >= k)        list.add(min.peek());      else        list.add(-1);    }    return list;  }   // Driver Code  public static void main(String[] args)  {    min = new PriorityQueue<>();     k = 4;     int arr[] = { 1, 2, 3, 4, 5, 6 };     List<Integer> res = getAllKthNumber(arr);     for (int x : res)      System.out.print(x + " ");  }     // This code is Contributed by Pradeep Mondal P}
// C# program for the above approachusing System;using System.Collections.Generic; public class GFG {   /*  using min heap DS   how data are stored in min Heap DS         1       2   3  if k==3 , then top element of heap  itself the kth largest largest element   */  static Queue<int> min;  static int k;   static List<int> getAllKthNumber(int []arr)  {     // list to store kth largest number    List<int> list = new List<int>();     // one by one adding values to the min heap    foreach (int val in arr) {       // if the heap size is less than k , we add to      // the heap      if (min.Count < k)        min.Enqueue(val);       /*      otherwise ,      first we  compare the current value with the      min heap TOP value       if TOP val > current element , no need to      remove TOP , bocause it will be the largest kth      element anyhow       else  we need to update the kth largest element      by removing the top lowest element      */      else {        if (val > min.Peek()) {          min.Dequeue();          min.Enqueue(val);        }      }       // if heap size >=k we add      // kth largest element      // otherwise -1       if (min.Count >= k)        list.Add(min.Peek());      else        list.Add(-1);    }    return list;  }   // Driver Code  public static void Main(String[] args)  {    min = new Queue<int>();    k = 4;    int []arr = { 1, 2, 3, 4, 5, 6 };    List<int> res = getAllKthNumber(arr);    foreach (int x in res)      Console.Write(x + " ");  }} // This code is contributed by shikhasingrajput
Output:
K is 3
Enter next element of stream 23
Enter next element of stream 10
Enter next element of stream 15
K'th largest element is 10
Enter next element of stream 70
K'th largest element is 15
Enter next element of stream 5
K'th largest element is 15
Enter next element of stream 80
K'th largest element is 23
Enter next element of stream 100
K'th largest element is 70
Enter next element of stream
CTRL + C pressed
Implementation using Priority Queue:
C++
Java
C#
// C++ program for the above approach#include <bits/stdc++.h>using namespace std; vector<int> kthLargest(int k, int arr[], int n){    vector<int> ans(n);     // Creating a min-heap using priority queue    priority_queue<int, vector<int>, greater<int> > pq;     // Iterating through each element    for (int i = 0; i < n; i++) {        // If size of priority        // queue is less than k        if (pq.size() < k)            pq.push(arr[i]);        else {            if (arr[i] > pq.top()) {                pq.pop();                pq.push(arr[i]);            }        }         // If size is less than k        if (pq.size() < k)            ans[i] = -1;        else            ans[i] = pq.top();    }     return ans;} // Driver Codeint main(){    int n = 6;    int arr[n] = { 1, 2, 3, 4, 5, 6 };    int k = 4;       // Function call    vector<int> v = kthLargest(k, arr, n);    for (auto it : v)        cout << it << " ";    return 0;}
// Java program for the above approachimport java.util.*; class GFG{   static int[] kthLargest(int k, int arr[], int n)  {    int []ans = new int[n];     // Creating a min-heap using priority queue    PriorityQueue<Integer> pq = new PriorityQueue<>((a,b)->a-b);     // Iterating through each element    for (int i = 0; i < n; i++)    {             // If size of priority      // queue is less than k      if (pq.size() < k)        pq.add(arr[i]);      else {        if (arr[i] > pq.peek()) {          pq.remove();          pq.add(arr[i]);        }      }       // If size is less than k      if (pq.size() < k)        ans[i] = -1;      else        ans[i] = pq.peek();    }     return ans;  }   // Driver Code  public static void main(String[] args)  {    int n = 6;    int arr[] = { 1, 2, 3, 4, 5, 6 };    int k = 4;     // Function call    int[] v = kthLargest(k, arr, n);    for (int it : v)      System.out.print(it+ " ");  }} // This code is contributed by shikhasingrajput
// C# program for the above approachusing System;using System.Collections.Generic;public class GFG{   static int[] kthLargest(int k, int []arr, int n)  {    int []ans = new int[n];     // Creating a min-heap using priority queue    List<int> pq = new List<int>();     // Iterating through each element    for (int i = 0; i < n; i++)    {             // If size of priority      // queue is less than k      if (pq.Count < k)        pq.Add(arr[i]);      else {        if (arr[i] > pq[0]) {          pq.Sort();          pq.RemoveAt(0);          pq.Add(arr[i]);        }      }       // If size is less than k      if (pq.Count < k)        ans[i] = -1;      else        ans[i] = pq[0];    }     return ans;  }   // Driver Code  public static void Main(String[] args)  {    int n = 6;    int []arr = { 1, 2, 3, 4, 5, 6 };    int k = 4;     // Function call    int[] v = kthLargest(k, arr, n);    foreach (int it in v)      Console.Write(it+ " ");  }}    // This code contributed by shikhasingrajput
-1 -1 -1 1 2 3 
This article is contributed by Shivam Gupta. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
pradeepmondalp
UtkarshPandey6
sooda367
kashishsoda
shikhasingrajput
Amazon
array-stream
Cisco
Order-Statistics
Arrays
Binary Search Tree
Heap
Searching
Amazon
Cisco
Arrays
Searching
Binary Search Tree
Heap
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Introduction to Arrays
Multidimensional Arrays in Java
Linked List vs Array
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Python | Using 2D arrays/lists the right way
Binary Search Tree | Set 1 (Search and Insertion)
AVL Tree | Set 1 (Insertion)
Binary Search Tree | Set 2 (Delete)
A program to check if a binary tree is BST or not
Construct BST from given preorder traversal | Set 1