Find top k (or most frequent) numbers in a stream - GeeksforGeeks

14 Mar, 2022
Given an array of n numbers. Your task is to read numbers from the array and keep at-most K numbers at the top (According to their decreasing frequency) every time a new number is read. We basically need to print top k numbers sorted by frequency when input stream has included k distinct elements, else need to print all distinct elements sorted by frequency.Examples:  
Input : arr[] = {5, 2, 1, 3, 2} k = 4 Output : 5 2 5 1 2 5 1 2 3 5 2 1 3 5 Explanation:  
After reading 5, there is only one element 5 whose frequency is max till now. so print 5.After reading 2, we will have two elements 2 and 5 with the same frequency. As 2, is smaller than 5 but their frequency is the same so we will print 2 5.After reading 1, we will have 3 elements 1, 2 and 5 with the same frequency, so print 1 2 5.Similarly after reading 3, print 1 2 3 5After reading last element 2 since 2 has already occurred so we have now a frequency of 2 as 2. So we keep 2 at the top and then rest of the element with the same frequency in sorted order. So print, 2 1 3 5.
After reading 5, there is only one element 5 whose frequency is max till now. so print 5.
After reading 2, we will have two elements 2 and 5 with the same frequency. As 2, is smaller than 5 but their frequency is the same so we will print 2 5.
After reading 1, we will have 3 elements 1, 2 and 5 with the same frequency, so print 1 2 5.
Similarly after reading 3, print 1 2 3 5
After reading last element 2 since 2 has already occurred so we have now a frequency of 2 as 2. So we keep 2 at the top and then rest of the element with the same frequency in sorted order. So print, 2 1 3 5.
Input : arr[] = {5, 2, 1, 3, 4} k = 4 Output : 5 2 5 1 2 5 1 2 3 5 1 2 3 4 Explanation:
After reading 5, there is only one element 5 whose frequency is max till now. so print 5.After reading 2, we will have two elements 2 and 5 with the same frequency. As 2, is smaller than 5 but their frequency is the same so we will print 2 5.After reading 1, we will have 3 elements 1, 2 and 5 with the same frequency, so print 1 2 5. Similarly after reading 3, print 1 2 3 5After reading last element 4, All the elements have same frequency So print, 1 2 3 4.
After reading 5, there is only one element 5 whose frequency is max till now. so print 5.
After reading 2, we will have two elements 2 and 5 with the same frequency. As 2, is smaller than 5 but their frequency is the same so we will print 2 5.
After reading 1, we will have 3 elements 1, 2 and 5 with the same frequency, so print 1 2 5. Similarly after reading 3, print 1 2 3 5
After reading last element 4, All the elements have same frequency So print, 1 2 3 4.
 
 
Approach: The idea is to store the top k elements with maximum frequency. To store them a vector or an array can be used. To keep the track of frequencies of elements creates a HashMap to store element-frequency pairs. Given a stream of numbers, when a new element appears in the stream update the frequency of that element in HashMap and put that element at the end of the list of K numbers (total k+1 elements) now compare adjacent elements of the list and swap if higher frequency element is stored next to it.Algorithm:  
Create a Hashmap hm, and an array of k + 1 length.Traverse the input array from start to end.Insert the element at k+1 th position of the array, update the frequency of that element in HashMap.Now, traverse the temp array from start to end – 1For very element, compare the frequency and swap if higher frequency element is stored next to it, if the frequency is same then swap is the next element is greater.print the top k element in each traversal of original array.
Create a Hashmap hm, and an array of k + 1 length.
Traverse the input array from start to end.
Insert the element at k+1 th position of the array, update the frequency of that element in HashMap.
Now, traverse the temp array from start to end – 1
For very element, compare the frequency and swap if higher frequency element is stored next to it, if the frequency is same then swap is the next element is greater.
print the top k element in each traversal of original array.
Implementation:  
C++
Java
Python3
C#
Javascript
// C++ program to find top k elements in a stream#include <bits/stdc++.h>using namespace std; // Function to print top k numbersvoid kTop(int a[], int n, int k){    // vector of size k+1 to store elements    vector<int> top(k + 1);     // array to keep track of frequency    unordered_map<int, int> freq;     // iterate till the end of stream    for (int m = 0; m < n; m++) {        // increase the frequency        freq[a[m]]++;         // store that element in top vector        top[k] = a[m];         // search in top vector for same element        auto it = find(top.begin(), top.end() - 1, a[m]);         // iterate from the position of element to zero        for (int i = distance(top.begin(), it) - 1; i >= 0; --i) {            // compare the frequency and swap if higher            // frequency element is stored next to it            if (freq[top[i]] < freq[top[i + 1]])                swap(top[i], top[i + 1]);             // if frequency is same compare the elements            // and swap if next element is high            else if ((freq[top[i]] == freq[top[i + 1]])                     && (top[i] > top[i + 1]))                swap(top[i], top[i + 1]);            else                break;        }         // print top k elements        for (int i = 0; i < k && top[i] != 0; ++i)            cout << top[i] << ' ';    }    cout << endl;} // Driver program to test above functionint main(){    int k = 4;    int arr[] = { 5, 2, 1, 3, 2 };    int n = sizeof(arr) / sizeof(arr[0]);    kTop(arr, n, k);    return 0;}
import java.io.*;import java.util.*;class GFG {     // function to search in top vector for element    static int find(int[] arr, int ele)    {        for (int i = 0; i < arr.length; i++)            if (arr[i] == ele)                return i;        return -1;    }     // Function to print top k numbers    static void kTop(int[] a, int n, int k)    {        // vector of size k+1 to store elements        int[] top = new int[k + 1];         // array to keep track of frequency        HashMap<Integer, Integer> freq = new HashMap<>();        for (int i = 0; i < k + 1; i++)            freq.put(i, 0);         // iterate till the end of stream        for (int m = 0; m < n; m++) {            // increase the frequency            if (freq.containsKey(a[m]))                freq.put(a[m], freq.get(a[m]) + 1);            else                freq.put(a[m], 1);             // store that element in top vector            top[k] = a[m];             // search in top vector for same element            int i = find(top, a[m]);            i -= 1;             // iterate from the position of element to zero            while (i >= 0) {                // compare the frequency and swap if higher                // frequency element is stored next to it                if (freq.get(top[i]) < freq.get(top[i + 1])) {                    int temp = top[i];                    top[i] = top[i + 1];                    top[i + 1] = temp;                }                 // if frequency is same compare the elements                // and swap if next element is high                else if ((freq.get(top[i]) == freq.get(top[i + 1])) && (top[i] > top[i + 1])) {                    int temp = top[i];                    top[i] = top[i + 1];                    top[i + 1] = temp;                }                 else                    break;                i -= 1;            }             // print top k elements            for (int j = 0; j < k && top[j] != 0; ++j)                System.out.print(top[j] + " ");        }        System.out.println();    }     // Driver program to test above function    public static void main(String args[])    {        int k = 4;        int[] arr = { 5, 2, 1, 3, 2 };        int n = arr.length;        kTop(arr, n, k);    }} // This code is contributed by rachana soma
# Python program to find top k elements in a stream # Function to print top k numbersdef kTop(a, n, k):     # list of size k + 1 to store elements    top = [0 for i in range(k + 1)]      # dictionary to keep track of frequency    freq = {i:0 for i in range(k + 1)}     # iterate till the end of stream    for m in range(n):         # increase the frequency        if a[m] in freq.keys():            freq[a[m]] += 1        else:            freq[a[m]] = 1         # store that element in top vector        top[k] = a[m]          i = top.index(a[m])        i -= 1                 while i >= 0:             # compare the frequency and swap if higher            # frequency element is stored next to it            if (freq[top[i]] < freq[top[i + 1]]):                t = top[i]                top[i] = top[i + 1]                top[i + 1] = t                         # if frequency is same compare the elements            # and swap if next element is high            else if ((freq[top[i]] == freq[top[i + 1]]) and (top[i] > top[i + 1])):                t = top[i]                top[i] = top[i + 1]                top[i + 1] = t            else:                break            i -= 1                 # print top k elements        i = 0        while i < k and top[i] != 0:            print(top[i],end=" ")            i += 1    print()  # Driver program to test above functionk = 4arr = [ 5, 2, 1, 3, 2 ]n = len(arr)kTop(arr, n, k) # This code is contributed by Sachin Bisht
// C# program to find top k elements in a streamusing System;using System.Collections.Generic; class GFG {    // function to search in top vector for element    static int find(int[] arr, int ele)    {        for (int i = 0; i < arr.Length; i++)            if (arr[i] == ele)                return i;        return -1;    }     // Function to print top k numbers    static void kTop(int[] a, int n, int k)    {        // vector of size k+1 to store elements        int[] top = new int[k + 1];         // array to keep track of frequency        Dictionary<int,                   int>            freq = new Dictionary<int,                                  int>();        for (int i = 0; i < k + 1; i++)            freq.Add(i, 0);         // iterate till the end of stream        for (int m = 0; m < n; m++) {            // increase the frequency            if (freq.ContainsKey(a[m]))                freq[a[m]]++;            else                freq.Add(a[m], 1);             // store that element in top vector            top[k] = a[m];             // search in top vector for same element            int i = find(top, a[m]);            i--;             // iterate from the position of element to zero            while (i >= 0) {                // compare the frequency and swap if higher                // frequency element is stored next to it                if (freq[top[i]] < freq[top[i + 1]]) {                    int temp = top[i];                    top[i] = top[i + 1];                    top[i + 1] = temp;                }                 // if frequency is same compare the elements                // and swap if next element is high                else if (freq[top[i]] == freq[top[i + 1]] && top[i] > top[i + 1]) {                    int temp = top[i];                    top[i] = top[i + 1];                    top[i + 1] = temp;                }                else                    break;                 i--;            }             // print top k elements            for (int j = 0; j < k && top[j] != 0; ++j)                Console.Write(top[j] + " ");        }        Console.WriteLine();    }     // Driver Code    public static void Main(String[] args)    {        int k = 4;        int[] arr = { 5, 2, 1, 3, 2 };        int n = arr.Length;        kTop(arr, n, k);    }} // This code is contributed by// sanjeev2552
<script>       // JavaScript program to find top k elements in a stream      // function to search in top vector for element      function find(arr, ele) {        for (var i = 0; i < arr.length; i++)        if (arr[i] === ele) return i;        return -1;      }       // Function to print top k numbers      function kTop(a, n, k) {        // vector of size k+1 to store elements        var top = new Array(k + 1).fill(0);         // array to keep track of frequency         var freq = {};        for (var i = 0; i < k + 1; i++) freq[i] = 0;         // iterate till the end of stream        for (var m = 0; m < n; m++) {          // increase the frequency          if (freq.hasOwnProperty(a[m])) freq[a[m]]++;          else freq[a[m]] = 1;           // store that element in top vector          top[k] = a[m];           // search in top vector for same element          var i = find(top, a[m]);          i--;           // iterate from the position of element to zero          while (i >= 0) {            // compare the frequency and swap if higher            // frequency element is stored next to it            if (freq[top[i]] < freq[top[i + 1]]) {              var temp = top[i];              top[i] = top[i + 1];              top[i + 1] = temp;            }             // if frequency is same compare the elements            // and swap if next element is high            else if (freq[top[i]] === freq[top[i + 1]] &&            top[i] > top[i + 1])            {              var temp = top[i];              top[i] = top[i + 1];              top[i + 1] = temp;            } else break;             i--;          }           // print top k elements          for (var j = 0; j < k && top[j] !== 0; ++j)            document.write(top[j] + " ");        }        document.write("<br>");      }       // Driver Code      var k = 4;      var arr = [5, 2, 1, 3, 2];      var n = arr.length;      kTop(arr, n, k);       </script>
5 2 5 1 2 5 1 2 3 5 2 1 3 5
 
Complexity Analysis:  
Time Complexity: O( n * k ). In each traversal the temp array of size k is traversed, So the time Complexity is O( n * k ).
Space Complexity:O(n). To store the elements in HashMap O(n) space is required.
This article is contributed by Niteesh Kumar. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
rachana soma
sanjeev2552
andrew1234
rdtank
amartyaghoshgfg
simmytarika5
Accolite
Amazon
array-stream
cpp-unordered_map
Order-Statistics
Arrays
Hash
Accolite
Amazon
Arrays
Hash
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Top 50 Array Coding Problems for Interviews
Introduction to Arrays
Multidimensional Arrays in Java
Linear Search
Linked List vs Array
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Internal Working of HashMap in Java
Count pairs with given sum
Hashing | Set 1 (Introduction)
Hashing | Set 3 (Open Addressing)