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.
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.
#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;
}
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();
}
}
}
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()
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();
}
}
}
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)