Find k most frequent in linear time
Last Updated :
03 Feb, 2022
Given an array of integers, we need to print k most frequent elements. If there is a tie, we need to prefer the elements whose first appearance is first.
Examples:
Input : arr[] = {10, 5, 20, 5, 10, 10, 30}, k = 2
Output : 10 5
Input : arr[] = {7, 7, 6, 6, 6, 7, 5, 4, 4, 10, 5}, k = 3
Output : 7 6 5
Explanation :
In this example, 7 and 6 have the same frequencies. We print 7 first because the first appearance of 7 is first. Similarly, 5 and 4 have the same frequencies. We prefer 5 because 5’s first appearance is first.
We have discussed two methods in the post below.
Find k numbers with most occurrences in the given array
Let us first talk about a simple solution that prints in any order in the case of a tie. Then we will discuss the solution that takes of the order.
The idea is to use hashing with frequency indexing. We first store counts in a hash. Then we traverse through the hash and use frequencies as the index to store elements with given frequencies. The important factor here is, the maximum frequency can be n. So an array of size n+1 would be good.
C++
#include <bits/stdc++.h>
using namespace std;
void print_N_mostFrequentNumber( int arr[], int n, int k)
{
unordered_map< int , int > um;
for ( int i = 0; i < n; i++)
um[arr[i]]++;
vector< int > freq[n + 1];
for ( auto x : um)
freq[x.second].push_back(x.first);
int count = 0;
for ( int i = n; i >= 0; i--) {
for ( int x : freq[i]) {
cout << x << " " ;
count++;
if (count == k)
return ;
}
}
}
int main()
{
int arr[] = { 3, 1, 4, 4, 5, 2, 6, 1 };
int n = sizeof (arr) / sizeof (arr[0]);
int k = 2;
print_N_mostFrequentNumber(arr, n, k);
return 0;
}
|
Java
import java.util.*;
public class KFrequentNumbers {
static void print_N_mostFrequentNumber( int [] arr, int n, int k)
{
Map<Integer, Integer> mp = new HashMap<Integer, Integer>();
for ( int i = 0 ; i < n; i++) {
mp.put(arr[i], mp.getOrDefault(arr[i], 0 ) + 1 );
}
List<List<Integer> > freq = new ArrayList<List<Integer> >();
for ( int i = 0 ; i <= n; i++)
freq.add( new ArrayList<Integer>());
for (Map.Entry<Integer, Integer> x : mp.entrySet())
freq.get(x.getValue()).add(x.getKey());
int count = 0 ;
for ( int i = n; i >= 0 ; i--) {
for ( int x : freq.get(i)) {
System.out.println(x);
count++;
if (count == k)
return ;
}
}
}
public static void main(String[] args)
{
int arr[] = { 3 , 1 , 4 , 4 , 5 , 2 , 6 , 1 };
int n = arr.length;
int k = 2 ;
print_N_mostFrequentNumber(arr, n, k);
}
}
|
Python3
def print_N_mostFrequentNumber(arr, n, k):
um = {}
for i in range (n):
um[arr[i]] = um.get(arr[i], 0 ) + 1
freq = [[] for i in range (n + 1 )]
for x in um:
freq[um[x]].append(x)
count = 0
for i in range (n, - 1 , - 1 ):
for x in sorted (freq[i])[:: - 1 ]:
print (x, end = " " )
count + = 1
if (count = = k):
return
if __name__ = = '__main__' :
arr = [ 3 , 1 , 4 , 4 , 5 , 2 , 6 , 1 ]
n = len (arr)
k = 2
print_N_mostFrequentNumber(arr, n, k)
|
C#
using System;
using System.Collections.Generic;
class KFrequentNumbers{
static void print_N_mostFrequentNumber( int [] arr,
int n, int k)
{
Dictionary< int ,
int > mp = new Dictionary< int ,
int >();
for ( int i = 0; i < n; i++)
{
if (mp.ContainsKey(arr[i]))
{
mp[arr[i]] = mp[arr[i]] + 1;
}
else
{
mp.Add(arr[i], 1);
}
}
List<List< int > > freq =
new List<List< int > >();
for ( int i = 0; i <= n; i++)
freq.Add( new List< int >());
foreach (KeyValuePair< int ,
int > x in mp)
freq[x.Value].Add(x.Key);
int count = 0;
for ( int i = n; i >= 0; i--)
{
foreach ( int x in freq[i])
{
Console.WriteLine(x);
count++;
if (count == k)
return ;
}
}
}
public static void Main(String[] args)
{
int []arr = {3, 1, 4, 4,
5, 2, 6, 1};
int n = arr.Length;
int k = 2;
print_N_mostFrequentNumber(arr, n, k);
}
}
|
Javascript
<script>
function print_N_mostFrequentNumber(arr, n, k)
{
let mp = new Map();
for (let i = 0; i < n; i++) {
mp.set(arr[i], mp.get(arr[i])== null ?1:mp.get(arr[i]) + 1);
}
let freq = [];
for (let i = 0; i <= n; i++)
freq.push([]);
for (let [key, value] of mp.entries())
freq[value].push(key);
let count = 0;
for (let i = n; i >= 0; i--) {
for (let x=0;x< freq[i].length;x++) {
document.write(freq[i][x]+ " " );
count++;
if (count == k)
return ;
}
}
}
let arr = [ 3, 1, 4, 4, 5, 2, 6, 1 ];
let n = arr.length;
let k = 2;
print_N_mostFrequentNumber(arr, n, k);
</script>
|
Time Complexity: O(n)
Auxiliary Space: O(n)
Printing according to the first appearance. To keep the required order, we traverse the original array instead of the map. To avoid duplicates, we need to mark processed entries as -1 on the map.
C++
#include <bits/stdc++.h>
using namespace std;
void print_N_mostFrequentNumber( int arr[], int n, int k)
{
unordered_map< int , int > um;
for ( int i = 0; i < n; i++)
um[arr[i]]++;
vector< int > freq[n + 1];
for ( int i = 0; i < n; i++) {
int f = um[arr[i]];
if (f != -1) {
freq[f].push_back(arr[i]);
um[arr[i]] = -1;
}
}
int count = 0;
for ( int i = n; i >= 0; i--) {
for ( int x : freq[i]) {
cout << x << " " ;
count++;
if (count == k)
return ;
}
}
}
int main()
{
int arr[] = { 3, 1, 4, 4, 5, 2, 6, 1 };
int n = sizeof (arr) / sizeof (arr[0]);
int k = 3;
print_N_mostFrequentNumber(arr, n, k);
return 0;
}
|
Java
import java.util.*;
public class KFrequentNumbers {
static void print_N_mostFrequentNumber( int [] arr, int n, int k)
{
Map<Integer, Integer> mp = new HashMap<Integer, Integer>();
for ( int i = 0 ; i < n; i++) {
mp.put(arr[i], mp.getOrDefault(arr[i], 0 ) + 1 );
}
List<List<Integer> > freq = new ArrayList<List<Integer> >();
for ( int i = 0 ; i <= n; i++)
freq.add( new ArrayList<Integer>());
for ( int i = 0 ; i < n; i++) {
int f = mp.get(arr[i]);
if (f != - 1 ) {
freq.get(f).add(arr[i]);
mp.put(arr[i], - 1 );
}
}
int count = 0 ;
for ( int i = n; i >= 0 ; i--) {
for ( int x : freq.get(i)) {
System.out.println(x);
count++;
if (count == k)
return ;
}
}
}
public static void main(String[] args)
{
int arr[] = { 3 , 1 , 4 , 4 , 5 , 2 , 6 , 1 };
int n = arr.length;
int k = 3 ;
print_N_mostFrequentNumber(arr, n, k);
}
}
|
Python3
def print_N_mostFrequentNumber(arr, n, k):
mp = {}
for i in range (n):
if arr[i] in mp:
mp[arr[i]] + = 1
else :
mp[arr[i]] = 0
freq = [[] for i in range (n + 1 )]
for i in range (n):
f = mp[arr[i]]
if (f ! = - 1 ):
freq[f].append(arr[i])
mp[arr[i]] = - 1
count = 0
for i in range (n, - 1 , - 1 ):
for x in freq[i]:
print (x ,end = " " )
count + = 1
if (count = = k):
return
arr = [ 3 , 1 , 4 , 4 , 5 , 2 , 6 , 1 ]
n = len (arr)
k = 3
print_N_mostFrequentNumber(arr, n, k)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static void print_N_mostFrequentNumber( int [] arr,
int n, int k)
{
Dictionary< int ,
int > mp = new Dictionary< int ,
int >();
for ( int i = 0; i < n; i++)
{
if (mp.ContainsKey(arr[i]))
mp[arr[i]]++;
else
mp.Add(arr[i], 0);
}
List<List< int >> freq = new List<List< int >>();
for ( int i = 0; i <= n; i++)
freq.Add( new List< int >());
for ( int i = 0; i < n; i++)
{
int f = mp[arr[i]];
if (f != -1)
{
freq[f].Add(arr[i]);
if (mp.ContainsKey(arr[i]))
mp[arr[i]] = -1;
else
mp.Add(arr[i], 0);
}
}
int count = 0;
for ( int i = n; i >= 0; i--)
{
foreach ( int x in freq[i])
{
Console.Write(x);
Console.Write( " " );
count++;
if (count == k)
return ;
}
}
}
public static void Main(String[] args)
{
int []arr = { 3, 1, 4, 4, 5, 2, 6, 1 };
int n = arr.Length;
int k = 3;
print_N_mostFrequentNumber(arr, n, k);
}
}
|
Javascript
<script>
function print_N_mostFrequentNumber(arr, n, k) {
var mp = {};
for ( var i = 0; i < n; i++) {
if (mp.hasOwnProperty(arr[i]))
mp[arr[i]]++;
else
mp[arr[i]] = 0;
}
var freq = Array.from(Array(n + 1), () => Array());
for ( var i = 0; i < n; i++) {
var f = mp[arr[i]];
if (f !== -1) {
freq[f].push(arr[i]);
if (mp.hasOwnProperty(arr[i]))
mp[arr[i]] = -1;
else
mp[arr[i]] = 0;
}
}
var count = 0;
for ( var i = n; i >= 0; i--) {
for (const x of freq[i]) {
document.write(x + " " );
count++;
if (count === k)
return ;
}
}
}
var arr = [3, 1, 4, 4, 5, 2, 6, 1];
var n = arr.length;
var k = 3;
print_N_mostFrequentNumber(arr, n, k);
</script>
|
Time Complexity: O(n)
Auxiliary Space: O(n)
Share your thoughts in the comments
Please Login to comment...