Top k Frequent in a Stream (original) (raw)

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 Yourselfredirect icon

Using Hash Map and Array

#include #include #include #include using namespace std;

vector<vector> kTop(vector& 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 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)