Skip to content
Related Articles

Related Articles

Find k most frequent in linear time
  • Difficulty Level : Hard
  • Last Updated : 30 Mar, 2021

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 same frequencies. We print 7 first because first appearance of 7 is first. Similarly, 5 and 4 have same frequencies. We prefer 5 because 5’s first appearance is first.

We have discussed two methods in the below post 
Find k numbers with most occurrences in the given array
Let us first talk about a simple solution that prints in any order in case of 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++




// C++ implementation to find k numbers with most
// occurrences in the given array
#include <bits/stdc++.h>
using namespace std;
 
// funnction to print the k numbers with most occurrences
void print_N_mostFrequentNumber(int arr[], int n, int k)
{
    // unordered_map 'um' implemented as frequency
    // hash table
    unordered_map<int, int> um;
    for (int i = 0; i < n; i++)
        um[arr[i]]++;
 
    // Use frequencies as indexes and put
    // elements with given frequency in a
    // vector (related to a frequency)
    vector<int> freq[n + 1];
    for (auto x : um)
        freq[x.second].push_back(x.first);
 
    // Initialize count of items printed
    int count = 0;
 
    // Traverse the frequency array from
    // right side as we need the most
    // frequent items.
    for (int i = n; i >= 0; i--) {
 
        // Print items of current frequency
        for (int x : freq[i]) {
            cout << x << " ";
            count++;
            if (count == k)
                return;
        }
    }
}
 
// Driver program to test above
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




// Java implementation to find k elements with max occurence.
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>();
 
        // Put count of all the distinct elements in Map
        // with element as the key & count as the value.
        for (int i = 0; i < n; i++) {
 
            // Get the count for the element if already
            // present in the Map or get the default value
            // which is 0.
            mp.put(arr[i], mp.getOrDefault(arr[i], 0) + 1);
        }
 
        // Initialize an array list of array lists
        List<List<Integer> > freq = new ArrayList<List<Integer> >();
        for (int i = 0; i <= n; i++)
            freq.add(new ArrayList<Integer>());
 
        // Use frequencies as indexes and add corresponding
        // values to the list
        for (Map.Entry<Integer, Integer> x : mp.entrySet())
            freq.get(x.getValue()).add(x.getKey());
 
        // Traverse freq[] from right side.
        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;
            }
        }
    }
 
    // Driver Code to test the code.
    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




# Python3 implementation to find k numbers
# with most occurrences in the given array
 
# Function to prthe k numbers with most occurrences
def print_N_mostFrequentNumber(arr, n, k):
     
    # unordered_map 'um' implemented as
    # frequency hash table
    um = {}
    for i in range(n):
        um[arr[i]] =  um.get(arr[i], 0) + 1
 
    # Use frequencies as indexes and put
    # elements with given frequency in a
    # vector (related to a frequency)
    freq = [[] for i in range(n + 1)]
    for x in um:
        freq[um[x]].append(x)
 
    # Initialize count of items printed
    count = 0
 
    # Traverse the frequency array from
    # right side as we need the most
    # frequent items.
    for i in range(n, -1, -1):
         
        # Print items of current frequency
        for x in sorted(freq[i])[::-1]:
            print(x, end = " ")
            count += 1
             
            if (count == k):
                return
 
# Driver code
if __name__ == '__main__':
     
    arr = [ 3, 1, 4, 4, 5, 2, 6, 1 ]
    n = len(arr)
    k = 2
     
    print_N_mostFrequentNumber(arr, n, k)
 
# This code is contributed by mohit kumar 29

C#




// C# implementation to find
// k elements with max occurence.
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>();
 
  // Put count of all the
  // distinct elements in Map
  // with element as the key
  // & count as the value.
  for (int i = 0; i < n; i++)
  {
    // Get the count for the
    // element if already
    // present in the Map
    // or get the default value
    // which is 0.
    if(mp.ContainsKey(arr[i]))
    {
      mp[arr[i]] = mp[arr[i]] + 1;
    }
    else
    {
      mp.Add(arr[i], 1);
    }
  }
 
  // Initialize an array
  // list of array lists
  List<List<int> > freq =
            new List<List<int> >();
   
  for (int i = 0; i <= n; i++)
    freq.Add(new List<int>());
 
  // Use frequencies as indexes
  // and add corresponding
  // values to the list
  foreach (KeyValuePair<int,
                        int> x in mp)
    freq[x.Value].Add(x.Key);
 
  // Traverse []freq from
  // right side.
  int count = 0;
  for (int i = n; i >= 0; i--)
  {
    foreach (int x in freq[i])
    {
      Console.WriteLine(x);
      count++;
      if (count == k)
        return;
    }
  }
}
 
// Driver Code to test the code.
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);
}
}
 
// This code is contributed by Princi Singh
Output: 
4 1

 

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 in the map.  

C++




// C++ implementation to find k numbers with most
// occurrences in the given array
#include <bits/stdc++.h>
using namespace std;
 
// function to print the k numbers with most occurrences
void print_N_mostFrequentNumber(int arr[], int n, int k)
{
    // unordered_map 'um' implemented as frequency
    // hash table
    unordered_map<int, int> um;
    for (int i = 0; i < n; i++)
        um[arr[i]]++;
 
    // Use frequencies as indexes and put
    // elements with given frequency in a
    // vector (related to a frequency)
    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;
        }
    }
 
    // Initialize count of items printed
    int count = 0;
 
    // Traverse the frequency array from
    // right side as we need the most
    // frequent items.
    for (int i = n; i >= 0; i--) {
 
        // Print items of current frequency
        for (int x : freq[i]) {
            cout << x << " ";
            count++;
            if (count == k)
                return;
        }
    }
}
 
// Driver program to test above
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




// Java implementation to find k elements with max occurence.
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>();
 
        // Put count of all the distinct elements in Map
        // with element as the key & count as the value.
        for (int i = 0; i < n; i++) {
 
            // Get the count for the element if already
            // present in the Map or get the default value
            // which is 0.
            mp.put(arr[i], mp.getOrDefault(arr[i], 0) + 1);
        }
 
        // Initialize an array list of array lists
        List<List<Integer> > freq = new ArrayList<List<Integer> >();
        for (int i = 0; i <= n; i++)
            freq.add(new ArrayList<Integer>());
 
        // Use frequencies as indexes and add corresponding
        // values to the list
        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);
            }
        }
 
        // Traverse freq[] from right side.
        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;
            }
        }
    }
 
    // Driver Code to test the code.
    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);
    }
}

C#




// C# implementation to find k elements
// with max occurence.
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>();
 
    // Put count of all the distinct
    // elements in Map with element
    // as the key & count as the value.
    for(int i = 0; i < n; i++)
    {
         
        // Get the count for the element
        // if already present in the Map
        // or get the default value which is 0.
        if (mp.ContainsKey(arr[i]))
            mp[arr[i]]++;
        else
            mp.Add(arr[i], 0);
    }
 
    // Initialize an array list of array lists
    List<List<int>> freq = new List<List<int>>();
    for(int i = 0; i <= n; i++)
        freq.Add(new List<int>());
 
    // Use frequencies as indexes and
    // add corresponding values to
    // the list
    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);
        }
    }
 
    // Traverse []freq from right side.
    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;
        }
    }
}
 
// Driver Code
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);
}
}
 
// This code is contributed by Amit Katiyar
Output: 
1 4 3

 

Time Complexity: O(n) 
Auxiliary Space: O(n)

My Personal Notes arrow_drop_up
Recommended Articles
Page :