Top k Frequent in a Stream

Last Updated : 1 May, 2026

Given an array of n numbers, process the elements one by one and maintain at most k elements with the highest frequency. After each insertion, include the elements sorted by decreasing frequency, and if frequencies are equal then smaller values come first. If the number of distinct elements is less than k, include all of them, otherwise include only the top k elements.

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:
1. After reading 5, only one element exists, so print 5.
2. After reading 2, both have the same frequency, so the smaller element comes first: 2 5.
3. After reading 1, all have the same frequency, so print in sorted order: 1 2 5.
4. After reading 3, all still have the same frequency, so print: 1 2 3 5.
5. After reading last 2, its frequency becomes highest, so it comes first, and the rest are printed in sorted order: 2 1 3 5.

Input: arr[] = {5, 2, 1, 4} k = 3
Output:
5
2 5
1 2 5
1 2 4
Explanation:
1. After reading 5, only one element exists, so print 5.
2. After reading 2, both have the same frequency, so the smaller element comes first: 2 5.
3. After reading 1, all have the same frequency, so print in sorted order: 1 2 5.
4. After reading 4, all elements have the same frequency, so print top k = 3 elements: 1 2 4.

Try It Yourself
redirect icon

Using Hash Map and Array

  • Maintain a Hash Map to store the frequency of each element.
  • Use an array of size k+1 to store current top elements.
  • For each incoming element, update its frequency and insert it at the correct position in the array. This step takes O(k) time.
C++
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;

vector<vector<int>> kTop(vector<int>& arr, int k) {
    
    vector<vector<int>> ans;

    // vector of size k+1 to maintain top k elements
    vector<int> top(k + 1, 0);

    // hashmap to store frequency of elements
    unordered_map<int, int> freq;

    // iterate till the end of stream
    for (int m = 0; m < arr.size(); m++) {

        // increase the frequency
        freq[arr[m]]++;

        // insert current element at last position
        top[k] = arr[m];

        // find position of current element in top k range
        auto it = find(top.begin(), top.begin() + k, arr[m]);

        // iterate from the position of element to zero
        for (int i = distance(top.begin(), it) - 1; i >= 0; --i) {
            
            // swap if next element has higher frequency
            if (freq[top[i]] < freq[top[i + 1]])
                swap(top[i], top[i + 1]);

            // if frequency same, swap if next element is smaller
            else if ((freq[top[i]] == freq[top[i + 1]])
                     && (top[i] > top[i + 1]))
                swap(top[i], top[i + 1]);
            else
                break;
        }

        // store current top k elements
        vector<int> curr;
        for (int i = 0; i < k && top[i] != 0; ++i)
            curr.push_back(top[i]);

        ans.push_back(curr);
    }

    return ans;
}

int main()
{
    int k = 4;
    vector<int> arr = {5, 2, 1, 3, 2};

    vector<vector<int>> result = kTop(arr, k);

    // print top k elements
    for (auto &vec : result) {
        for (int x : vec) {
            cout << x << " ";
        }
        cout << endl;
    }

    return 0;
}
Java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Collections;

class GfG {

    static ArrayList<ArrayList<Integer>> kTop(int[] arr, int k) {

        ArrayList<ArrayList<Integer>> ans = new ArrayList<>();

        // array of size k+1 to maintain top k elements
        int[] top = new int[k + 1];

        // hashmap to store frequency of elements
        HashMap<Integer, Integer> freq = new HashMap<>();

        int size = 0;

        // iterate through the stream
        for (int m = 0; m < arr.length; m++) {

            // update frequency
            freq.put(arr[m], freq.getOrDefault(arr[m], 0) + 1);

            // check if element already exists in top
            int idx = -1;
            for (int i = 0; i < size; i++) {
                if (top[i] == arr[m]) {
                    idx = i;
                    break;
                }
            }

            // if not present, insert at end
            if (idx == -1) {
                if (size < k) {
                    top[size] = arr[m];
                    idx = size;
                    size++;
                } else {
                    top[k] = arr[m];
                    idx = k;
                }
            }

            // move element to correct position
            while (idx > 0) {

                int curr = top[idx];
                int prev = top[idx - 1];

                int freqCurr = freq.get(curr);
                int freqPrev = freq.get(prev);

                // swap if needed
                if (freqCurr > freqPrev ||
                   (freqCurr == freqPrev && curr < prev)) {

                    int temp = top[idx];
                    top[idx] = top[idx - 1];
                    top[idx - 1] = temp;

                    idx--;
                } else {
                    break;
                }
            }

            // collect current top k elements
            ArrayList<Integer> currList = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                currList.add(top[i]);
            }

            ans.add(currList);
        }

        return ans;
    }

    public static void main(String[] args) {

        int k = 4;
        int[] arr = {5, 2, 1, 3, 2};

        ArrayList<ArrayList<Integer>> result = kTop(arr, k);

        // print result
        for (ArrayList<Integer> vec : result) {
            for (int x : vec) {
                System.out.print(x + " ");
            }
            System.out.println();
        }
    }
}
Python
from collections import defaultdict

def kTop(arr, k):
    
    ans = []

    # list of size k+1 to maintain top k elements
    top = [0 for _ in range(k + 1)]

    # hashmap to store frequency of elements
    freq = defaultdict(int)

    # iterate through the stream
    for m in range(len(arr)):

        # update frequency of current element
        freq[arr[m]] += 1

        # insert current element at last position
        top[k] = arr[m]

        # find position of current element within top k range
        idx = k
        for i in range(k):
            if top[i] == arr[m]:
                idx = i
                break

        # move element towards correct position
        i = idx - 1
        while i >= 0:

            # store frequencies to avoid repeated lookup
            f1 = freq[top[i]]
            f2 = freq[top[i + 1]]

            # swap if next element has higher frequency
            if f1 < f2:
                top[i], top[i + 1] = top[i + 1], top[i]

            # if frequencies are equal, place smaller element first
            elif (f1 == f2 and top[i] > top[i + 1]):
                top[i], top[i + 1] = top[i + 1], top[i]

            else:
                break

            i -= 1

        # collect current top k elements
        curr = []
        for i in range(k):
            if top[i] != 0:
                curr.append(top[i])
            else:
                break

        ans.append(curr)

    return ans


if __name__ == "__main__":
    k = 4
    arr = [5, 2, 1, 3, 2]

    result = kTop(arr, k)

    # print top k elements
    for vec in result:
        for x in vec:
            print(x, end=" ")
        print()
C#
using System;
using System.Collections.Generic;

class GfG {

    static List<List<int>> kTop(int[] arr, int k) {
        
        List<List<int>> ans = new List<List<int>>();

        // array of size k+1 to maintain top k elements
        int[] top = new int[k + 1];

        // hashmap to store frequency of elements
        Dictionary<int, int> freq = new Dictionary<int, int>();

        // iterate through the stream
        for (int m = 0; m < arr.Length; m++) {

            // update frequency of current element
            if (freq.ContainsKey(arr[m]))
                freq[arr[m]]++;
            else
                freq[arr[m]] = 1;

            // insert current element at last position
            top[k] = arr[m];

            // find position of current element within top k range
            int idx = k;
            for (int i = 0; i < k; i++) {
                if (top[i] == arr[m]) {
                    idx = i;
                    break;
                }
            }

            // move element towards correct position
            for (int i = idx - 1; i >= 0; --i) {
                
                // swap if next element has higher frequency
                int freq_i = freq.ContainsKey(top[i]) ? 
                                            freq[top[i]] : 0;
                int freq_next = freq.ContainsKey(top[i + 1]) ? 
                                            freq[top[i + 1]] : 0;

                if (freq_i < freq_next) {
                    int temp = top[i];
                    top[i] = top[i + 1];
                    top[i + 1] = temp;
                }

                // if frequencies are equal, place smaller element first
                else if (freq_i == freq_next && top[i] > top[i + 1]) {
                    int temp = top[i];
                    top[i] = top[i + 1];
                    top[i + 1] = temp;
                }
                else
                    break;
            }

            // collect current top k elements
            List<int> curr = new List<int>();
            for (int i = 0; i < k && top[i] != 0; ++i)
                curr.Add(top[i]);

            ans.Add(curr);
        }

        return ans;
    }

    public static void Main(string[] args)
    {
        int k = 4;
        int[] arr = { 5, 2, 1, 3, 2 };

        List<List<int>> result = kTop(arr, k);

        // print top k elements
        foreach (var vec in result) {
            foreach (int x in vec) {
                Console.Write(x + " ");
            }
            Console.WriteLine();
        }
    }
}
JavaScript
function kTop(arr, k) {

  let ans = [];

  // array of size k+1 to maintain top k elements
  let top = new Array(k + 1).fill(0);

  // object to store frequency of elements
  let freq = {};

  // iterate through the stream
  for (let m = 0; m < arr.length; m++) {

    // update frequency of current element
    freq[arr[m]] = (freq[arr[m]] || 0) + 1;

    // insert current element at last position
    top[k] = arr[m];

    // find position of current element within top k range
    let idx = k;
    for (let i = 0; i < k; i++) {
      if (top[i] === arr[m]) {
        idx = i;
        break;
      }
    }

    // move element towards correct position
    for (let i = idx - 1; i >= 0; --i) {

      // swap if next element has higher frequency
      if ((freq[top[i]] || 0) < (freq[top[i + 1]] || 0)) {
        let temp = top[i];
        top[i] = top[i + 1];
        top[i + 1] = temp;
      }

      // if frequencies are equal, place smaller element first
      else if (((freq[top[i]] || 0) === (freq[top[i + 1]] || 0)) &&
               (top[i] > top[i + 1])) {
        let temp = top[i];
        top[i] = top[i + 1];
        top[i + 1] = temp;
      }

      else
        break;
    }

    // collect current top k elements
    let curr = [];
    for (let i = 0; i < k && top[i] !== 0; ++i) {
      curr.push(top[i]);
    }

    ans.push(curr);
  }

  return ans;
}


// Driver Code
let k = 4;
let arr = [5, 2, 1, 3, 2];

let result = kTop(arr, k);

// print top k elements
for (let vec of result) {
  let row = "";
  for (let x of vec) {
    row += x + " ";
  }
  console.log(row.trim());
}

Output
5 
2 5 
1 2 5 
1 2 3 5 
2 1 3 5 

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)

Comment