K’th largest element in a stream
Last Updated :
30 Dec, 2022
Given an infinite stream of integers, find the Kth largest element at any point of time.
Note: Here we have a stream instead of a whole array and we are allowed to store only K elements.
Examples:
Input: stream[] = {10, 20, 11, 70, 50, 40, 100, 5, . . .}, K = 3
Output: {_, _, 10, 11, 20, 40, 50, 50, . . .}
Input: stream[] = {2, 5, 1, 7, 9, . . .}, K = 2
Output: {_, 2, 2, 5, 7, . . .}
Naive Approach: To solve the problem follow the below idea:
Keep an array of size K. The idea is to keep the array sorted so that the Kth largest element can be found in O(1) time (we just need to return the first element of the array, if the array is sorted in increasing order
How to process a new element of the stream?
For every new element in the stream, check if the new element is smaller than the current Kth largest element. If yes, then ignore it. If no, then remove the smallest element from the array and insert the new element in sorted order.
The time complexity of processing a new element is O(K)
To solve the problem follow the below idea:
Create a self-balancing binary search tree and for every new element in the stream, check if the new element is smaller than the current k’th largest element. If yes, then ignore it. If no, then remove the smallest element from the tree and insert a new element.
The Kth largest element can be found in O(log K) time.
Kth largest element in a stream using a Min-Heap:
To solve the problem follow the below idea:
An Efficient Solution is to use a Min Heap of size K to store K largest elements of the stream. The Kth largest element is always at the root and can be found in O(1) time
How to process a new element of the stream?
Compare the new element with the root of the heap. If a new element is smaller, then ignore it. Otherwise, replace the root with a new element and call heapify for the root of the modified heap
Below is the implementation of the above approach:
CPP
#include <bits/stdc++.h>
using namespace std;
void swap( int * x, int * y);
class MinHeap {
int * harr;
int capacity;
int heap_size;
public :
MinHeap( int a[], int size);
void buildHeap();
void MinHeapify(
int 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();
int getMin() { return harr[0]; }
void replaceMin( int x)
{
harr[0] = x;
MinHeapify(0);
}
};
MinHeap::MinHeap( int a[], int size)
{
heap_size = size;
harr = a;
}
void MinHeap::buildHeap()
{
int i = (heap_size - 1) / 2;
while (i >= 0) {
MinHeapify(i);
i--;
}
}
int MinHeap::extractMin()
{
if (heap_size == 0)
return INT_MAX;
int root = harr[0];
if (heap_size > 1) {
harr[0] = harr[heap_size - 1];
MinHeapify(0);
}
heap_size--;
return root;
}
void 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);
}
}
void swap( int * x, int * y)
{
int temp = *x;
*x = *y;
*y = temp;
}
void kthLargest( int k, vector< int >& A)
{
int count = 0, x;
int * arr = new int [k];
MinHeap mh(arr, k);
for ( auto & x : A) {
if (count < k - 1) {
arr[count] = x;
count++;
cout << "Kth largest element is -1 " << endl;
}
else {
if (count == k - 1) {
arr[count] = x;
mh.buildHeap();
}
else {
if (x > mh.getMin())
mh.replaceMin(x);
}
cout << "Kth largest element is "
<< mh.getMin() << endl;
count++;
}
}
}
int main()
{
vector< int > arr = { 1, 2, 3, 4, 5, 6 };
int K = 3;
kthLargest(K, arr);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static PriorityQueue<Integer> min;
static int k;
static List<Integer> getAllKthNumber( int arr[])
{
List<Integer> list = new ArrayList<>();
for ( int val : arr) {
if (min.size() < k)
min.add(val);
else {
if (val > min.peek()) {
min.poll();
min.add(val);
}
}
if (min.size() >= k)
list.add(min.peek());
else
list.add(- 1 );
}
return list;
}
public static void main(String[] args)
{
min = new PriorityQueue<>();
k = 3 ;
int arr[] = { 1 , 2 , 3 , 4 , 5 , 6 };
List<Integer> res = getAllKthNumber(arr);
for ( int x : res)
System.out.println( "Kth largest element is "
+ x);
}
}
|
Python
import heapq
min = []
k = 3
def getAllKthNumber(arr):
list = []
for val in arr:
if len ( min ) < k:
heapq.heappush( min , val)
else :
if val > min [ 0 ]:
heapq.heappop( min )
heapq.heappush( min , val)
if len ( min ) > = k:
list .append( min [ 0 ])
else :
list .append( - 1 )
return list
arr = [ 1 , 2 , 3 , 4 , 5 , 6 ]
res = getAllKthNumber(arr)
for x in res:
print ( "Kth largest element is" , x)
|
C#
using System;
using System.Collections.Generic;
public class GFG {
static Queue< int > min;
static int k;
static List< int > getAllKthNumber( int [] arr)
{
List< int > list = new List< int >();
foreach ( int val in arr)
{
if (min.Count < k)
min.Enqueue(val);
else {
if (val > min.Peek()) {
min.Dequeue();
min.Enqueue(val);
}
}
if (min.Count >= k)
list.Add(min.Peek());
else
list.Add(-1);
}
return list;
}
public static void Main(String[] args)
{
min = new Queue< int >();
k = 3;
int [] arr = { 1, 2, 3, 4, 5, 6 };
List< int > res = getAllKthNumber(arr);
foreach ( int x in res) Console.Write(
"Kth largest element is " + x + "\n" );
}
}
|
Javascript
function getAllKthNumber(arr) {
const min = [];
const k = 3;
const list = [];
for (const val of arr) {
if (min.length < k) {
min.push(val);
min.sort((a, b) => a - b);
}
else {
if (val > min[0]) {
min.shift();
min.push(val);
min.sort((a, b) => a - b);
}
}
if (min.length >= k) {
list.push(min[0]);
} else {
list.push(-1);
}
}
return list;
}
const arr = [1, 2, 3, 4, 5, 6];
const res = getAllKthNumber(arr);
for (const x of res) {
console.log( 'Kth largest element is' , x);
}
|
Output
Kth largest element is -1
Kth largest element is -1
Kth largest element is 1
Kth largest element is 2
Kth largest element is 3
Kth largest element is 4
Time Complexity: O(N * log K)
Auxiliary Space: O(K)
Below is the implementation of the above approach using priority-queue:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > kthLargest( int k, int arr[], int n)
{
vector< int > ans(n);
priority_queue< int , vector< int >, greater< int > > pq;
for ( int i = 0; i < n; i++) {
if (pq.size() < k)
pq.push(arr[i]);
else {
if (arr[i] > pq.top()) {
pq.pop();
pq.push(arr[i]);
}
}
if (pq.size() < k)
ans[i] = -1;
else
ans[i] = pq.top();
}
return ans;
}
int main()
{
int n = 6;
int arr[n] = { 1, 2, 3, 4, 5, 6 };
int k = 4;
vector< int > v = kthLargest(k, arr, n);
for ( auto it : v)
cout << it << " " ;
return 0;
}
|
Java
import java.util.*;
class GFG {
static int [] kthLargest( int k, int arr[], int n)
{
int [] ans = new int [n];
PriorityQueue<Integer> pq
= new PriorityQueue<>((a, b) -> a - b);
for ( int i = 0 ; i < n; i++) {
if (pq.size() < k)
pq.add(arr[i]);
else {
if (arr[i] > pq.peek()) {
pq.remove();
pq.add(arr[i]);
}
}
if (pq.size() < k)
ans[i] = - 1 ;
else
ans[i] = pq.peek();
}
return ans;
}
public static void main(String[] args)
{
int n = 6 ;
int arr[] = { 1 , 2 , 3 , 4 , 5 , 6 };
int k = 4 ;
int [] v = kthLargest(k, arr, n);
for ( int it : v)
System.out.print(it + " " );
}
}
|
Python3
from queue import PriorityQueue
def kthLargest(k, arr, n):
ans = [ 0 ] * n
pq = PriorityQueue()
for i in range (n):
if (pq.qsize() < k):
pq.put(arr[i])
else :
if (arr[i] > pq.queue[ 0 ]):
pq.get()
pq.put(arr[i])
if (pq.qsize() < k):
ans[i] = - 1
else :
ans[i] = pq.queue[ 0 ]
return ans
if __name__ = = "__main__" :
n = 6
arr = [ 1 , 2 , 3 , 4 , 5 , 6 ]
k = 4
v = kthLargest(k, arr, n)
print ( * v)
|
C#
using System;
using System.Collections.Generic;
public class GFG {
static int [] kthLargest( int k, int [] arr, int n)
{
int [] ans = new int [n];
List< int > pq = new List< int >();
for ( int i = 0; i < n; i++) {
if (pq.Count < k)
pq.Add(arr[i]);
else {
if (arr[i] > pq[0]) {
pq.Sort();
pq.RemoveAt(0);
pq.Add(arr[i]);
}
}
if (pq.Count < k)
ans[i] = -1;
else
ans[i] = pq[0];
}
return ans;
}
public static void Main(String[] args)
{
int n = 6;
int [] arr = { 1, 2, 3, 4, 5, 6 };
int k = 4;
int [] v = kthLargest(k, arr, n);
foreach ( int it in v) Console.Write(it + " " );
}
}
|
Javascript
function kthLargest(k, arr, n) {
const ans = new Array(n);
const pq = [];
for (let i = 0; i < n; i++) {
if (pq.length < k) pq.push(arr[i]);
else {
if (arr[i] > pq[0]) {
pq.sort();
pq.shift();
pq.push(arr[i]);
}
}
if (pq.length < k) ans[i] = -1;
else ans[i] = pq[0];
}
return ans;
}
const n = 6;
const arr = [1, 2, 3, 4, 5, 6];
const k = 4;
const v = kthLargest(k, arr, n);
console.log(v.join( ' ' ));
|
Time Complexity: O(N * log K)
Auxiliary Space: O(K)
Related Articles:
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)
Please Login to comment...