Sorting element of an array by frequency in decreasing order
Given an array arr[] of N integers. The task is to sort the array arr[] according to the frequency of elements in decreasing order.
Note: If the frequencies of the two elements are the same, then the smaller element should come first.
Examples:
Input: arr[] = { 4, 4, 5, 6, 4, 2, 2, 8, 5 }
Output: 4 4 4 2 2 5 5 6 8Input: arr[] = { 9, 9, 5, 8, 5 }
Output: 5 5 9 9 8
Approach:
- Store the frequency of all elements in array arr[].
- For arr[] = { 4, 4, 5, 6, 4, 2, 2, 8, 5 }
The frequency array of the above array is:
freq[] = { 0, 0, 2, 0, 3, 2, 0, 1, 0, 1} - Traverse the frequency array and for all the element having frequency greater than 1, update the value in the array arr[] as:
freq[2] = 2
arr[0] = 100000*freq[2] + (100000 – 2) = 299998
freq[4] = 3
arr[1] = 100000*freq[2] + (100000 – 4) = 399996
freq[5] = 2
arr[2] = 100000*freq[2] + (100000 – 5) = 299995
freq[6] = 2
arr[3] = 100000*freq[2] + (100000 – 6) = 199994
freq[8] = 2
arr[4] = 100000*freq[2] + (100000 – 2) = 199994
Now array becomes:
arr[] = {299998, 399996, 299995, 199994, 199992, 2, 2, 8, 5}
To get the frequency of current element:
frequency = arr[i]/100000;
To get the value:
value = 100000 – arr[i]%100000
For Example:
if arr[i] = 399996
frequency = arr[i]/100000 = 399996/100000 = 3
value = 100000 – arr[i]%100000 = 100000 – 99996 = 4
The element 4 is having frequency 3.
- For each element in arr[] find the value and frequency(say f) at each index and print the value f number of times.
Below is the implementation of the above approach:
C++
// C++ program to sort an array in // decreasing order of their frequency #include "bits/stdc++.h" using namespace std; // Function that return the index // upto all the array elements are // updated. int sortByFreq( int * arr, int n) { // Initialise maxE = -1 int maxE = -1; // Find the maximum element of // arr[] for ( int i = 0; i < n; i++) { maxE = max(maxE, arr[i]); } // Create frequency array freq[] int freq[maxE + 1] = { 0 }; // Update the frequency array as // per the occurrence of element in // arr[] for ( int i = 0; i < n; i++) { freq[arr[i]]++; } // Initialise cnt to 0 int cnt = 0; // Traversing freq[] for ( int i = 0; i <= maxE; i++) { // If freq of an element is // greater than 0 update the // value of arr[] at index cnt // & increment cnt if (freq[i] > 0) { int value = 100000 - i; arr[cnt] = 100000 * freq[i] + value; cnt++; } } // Return cnt return cnt; } // Function that print array arr[] // elements in sorted order void printSortedArray( int * arr, int cnt) { // Traversing arr[] till index cnt for ( int i = 0; i < cnt; i++) { // Find frequency of elements int frequency = arr[i] / 100000; // Find value at index i int value = 100000 - (arr[i] % 100000); // Traversing till frequency // to print value at index i for ( int j = 0; j < frequency; j++) { cout << value << ' ' ; } } } // Driver code int main() { int arr[] = { 4, 4, 5, 6, 4, 2, 2, 8, 5 }; // Size of array arr[] int n = sizeof (arr) / sizeof (arr[0]); // Function call to get cnt int cnt = sortByFreq(arr, n); // Sort the arr[] in decreasing order sort(arr, arr + cnt, greater< int >()); // Function that prints elements // in decreasing order printSortedArray(arr, cnt); return 0; } |
Java
// Java program to sort an array in // decreasing order of their frequency import java.util.*; class GFG{ // Function that return the index // upto all the array elements are // updated. static int sortByFreq(Integer []arr, int n) { // Initialise maxE = -1 int maxE = - 1 ; // Find the maximum element of // arr[] for ( int i = 0 ; i < n; i++) { maxE = Math.max(maxE, arr[i]); } // Create frequency array freq[] int freq[] = new int [maxE + 1 ]; // Update the frequency array as // per the occurrence of element in // arr[] for ( int i = 0 ; i < n; i++) { freq[arr[i]]++; } // Initialise cnt to 0 int cnt = 0 ; // Traversing freq[] for ( int i = 0 ; i <= maxE; i++) { // If freq of an element is // greater than 0 update the // value of arr[] at index cnt // & increment cnt if (freq[i] > 0 ) { int value = 100000 - i; arr[cnt] = 100000 * freq[i] + value; cnt++; } } // Return cnt return cnt; } // Function that print array arr[] // elements in sorted order static void printSortedArray(Integer []arr, int cnt) { // Traversing arr[] till index cnt for ( int i = 0 ; i < cnt; i++) { // Find frequency of elements int frequency = arr[i] / 100000 ; // Find value at index i int value = 100000 - (arr[i] % 100000 ); // Traversing till frequency // to print value at index i for ( int j = 0 ; j < frequency; j++) { System.out.print(value + " " ); } } } // Driver code public static void main(String[] args) { Integer arr[] = { 4 , 4 , 5 , 6 , 4 , 2 , 2 , 8 , 5 }; // Size of array arr[] int n = arr.length; // Function call to get cnt int cnt = sortByFreq(arr, n); // Sort the arr[] in decreasing order Arrays.sort(arr, Collections.reverseOrder()); // Function that prints elements // in decreasing order printSortedArray(arr, cnt); } } // This code is contributed by sapnasingh4991 |
Python3
# Python program to sort an array in # decreasing order of their frequency # Function that return the index # upto all the array elements are # updated. def sortByFreq(arr, n): # Initialise maxE = -1 maxE = - 1 ; # Find the maximum element of # arr[] for i in range (n): maxE = max (maxE, arr[i]) # Create frequency array freq[] freq = [ 0 ] * (maxE + 1 ); # Update the frequency array as # per the occurrence of element in # arr[] for i in range (n): freq[arr[i]] + = 1 ; # Initialise cnt to 0 cnt = 0 ; # Traversing freq[] for i in range (maxE + 1 ): # If freq of an element is # greater than 0 update the # value of arr[] at index cnt # & increment cnt if (freq[i] > 0 ): value = 100000 - i; arr[cnt] = 100000 * freq[i] + value; cnt + = 1 ; # Return cnt return cnt; # Function that print array arr[] # elements in sorted order def printSortedArray(arr, cnt): # Traversing arr[] till index cnt for i in range (cnt): # Find frequency of elements frequency = arr[i] / 100000 ; # Find value at index i value = 100000 - (arr[i] % 100000 ); # Traversing till frequency # to print value at index i for j in range ( int (frequency)): print (value, end = " " ) # Driver code if __name__ = = '__main__' : arr = [ 4 , 4 , 5 , 6 , 4 , 2 , 2 , 8 , 5 ] # Size of array arr[] n = len (arr) # Function call to get cnt cnt = sortByFreq(arr, n); # Sort the arr[] in decreasing order arr.sort(reverse = True ) # Function that prints elements # in decreasing order printSortedArray(arr, cnt); # This code is contributed by Princi Singh |
C#
// C# program to sort an array in // decreasing order of their frequency using System; class GFG { // Function that return the index // upto all the array elements are // updated. static int sortByFreq( int [] arr, int n) { // Initialise maxE = -1 int maxE = -1; // Find the maximum element of // arr[] for ( int i = 0; i < n; i++) { maxE = Math.Max(maxE, arr[i]); } // Create frequency array freq[] int [] freq = new int [maxE + 1]; // Update the frequency array as // per the occurrence of element in // arr[] for ( int i = 0; i < n; i++) { freq[arr[i]]++; } // Initialise cnt to 0 int cnt = 0; // Traversing freq[] for ( int i = 0; i <= maxE; i++) { // If freq of an element is // greater than 0 update the // value of arr[] at index cnt // & increment cnt if (freq[i] > 0) { int value = 100000 - i; arr[cnt] = 100000 * freq[i] + value; cnt++; } } // Return cnt return cnt; } // Function that print array arr[] // elements in sorted order static void printSortedArray( int [] arr, int cnt) { // Traversing arr[] till index cnt for ( int i = 0; i < cnt; i++) { // Find frequency of elements int frequency = arr[i] / 100000; // Find value at index i int value = 100000 - (arr[i] % 100000); // Traversing till frequency // to print value at index i for ( int j = 0; j < frequency; j++) { Console.Write(value + " " ); } } } // Driver code public static void Main() { int [] arr = { 4, 4, 5, 6, 4, 2, 2, 8, 5 }; // Size of array arr[] int n = arr.Length; // Function call to get cnt int cnt = sortByFreq(arr, n); // Sort the arr[] in decreasing order Array.Sort(arr); Array.Reverse(arr); // Function that prints elements // in decreasing order printSortedArray(arr, cnt); } } // This code is contributed by subhamahato348 |
Javascript
<script> // JavaScript program to sort an array in // decreasing order of their frequency // Function that return the index // upto all the array elements are // updated. function sortByFreq(arr, n) { // Initialise maxE = -1 var maxE = -1; // Find the maximum element of // arr[] for ( var i = 0; i < n; i++) { maxE = Math.max(maxE, arr[i]); } // Create frequency array freq[] var freq = new Array(maxE + 1).fill(0); // Update the frequency array as // per the occurrence of element in // arr[] for ( var i = 0; i < n; i++) { freq[arr[i]]++; } // Initialise cnt to 0 var cnt = 0; // Traversing freq[] for ( var i = 0; i <= maxE; i++) { // If freq of an element is // greater than 0 update the // value of arr[] at index cnt // & increment cnt if (freq[i] > 0) { var value = 100000 - i; arr[cnt] = 100000 * freq[i] + value; cnt++; } } // Return cnt return cnt; } // Function that print array arr[] // elements in sorted order function printSortedArray(arr, cnt) { // Traversing arr[] till index cnt for ( var i = 0; i < cnt; i++) { // Find frequency of elements var frequency = parseInt(arr[i] / 100000); // Find value at index i var value = 100000 - (arr[i] % 100000); // Traversing till frequency // to print value at index i for ( var j = 0; j < frequency; j++) { document.write(value + " " ); } } } // Driver code var arr = [4, 4, 5, 6, 4, 2, 2, 8, 5]; // Size of array arr[] var n = arr.length; // Function call to get cnt var cnt = sortByFreq(arr, n); // Sort the arr[] in decreasing order arr.sort((a, b) => b - a); // Function that prints elements // in decreasing order printSortedArray(arr, cnt); </script> |
4 4 4 2 2 5 5 6 8
Time Complexity: O(N*log N)
Auxiliary Space: O(N)
STL Pair and Comparator based approach :
Approach:
1. Store the frequency of each element in a map.
2. Iterate the map and store the each element and it’s frequency in a vector of pairs.
3. Pass a comparator which sorts the elements in decreasing order of their frequency and by elements value if frequency is equal.
4.Push the elements their frequency number of times inside the final array.
C++
#include<bits/stdc++.h> using namespace std; bool compare(pair< int , int >p1,pair< int , int >p2) { if (p1.second==p2.second) //if frequency is equal { return p1.first<p2.first; //return the smaller value } return p1.second>p2.second; //return the element with greater frequency } int main() { vector< int >arr={4,4,5,6,4,2,2,8,5}; int n=arr.size(); map< int , int >m; for ( int i=0;i<n;i++) { m[arr[i]]+=1; } vector<pair< int , int >>a; for ( auto it=m.begin();it!=m.end();it++) { a.push_back(make_pair(it->first,it->second)); //making pair of element and it's frequency } sort(a.begin(),a.end(),compare); vector< int >ans; for ( auto x:a) { while (x.second--) { ans.push_back(x.first); } } for ( auto x:ans) { cout<<x<< " " ; } return 0; } |
Java
// Java code for the approach import java.util.*; public class Main { public static int compare( int [] p1, int [] p2) { if (p1[ 1 ] == p2[ 1 ]) //if frequency is equal { return p1[ 0 ] - p2[ 0 ]; //return the smaller value } return p2[ 1 ] - p1[ 1 ]; //return the element with greater frequency } public static void main(String[] args) { int [] arr = { 4 , 4 , 5 , 6 , 4 , 2 , 2 , 8 , 5 }; int n = arr.length; Map<Integer, Integer> m = new HashMap<Integer, Integer>(); for ( int i = 0 ; i < n; i++) { if (m.containsKey(arr[i])) { m.put(arr[i], m.get(arr[i]) + 1 ); } else m.put(arr[i], 1 ); } int [][] a = new int [m.size()][ 2 ]; int i = 0 ; for (Map.Entry<Integer, Integer> x : m.entrySet()) { a[i][ 0 ] = x.getKey(); a[i][ 1 ] = x.getValue(); i++; } Arrays.sort(a, Main::compare); int [] ans = new int [n]; int j = 0 ; for ( int [] x : a) { while (x[ 1 ]-- > 0 ) { ans[j++] = x[ 0 ]; } } for ( int x : ans) { System.out.print(x + " " ); } } } |
Python3
# Python code for the approach from functools import cmp_to_key def compare(p1, p2): if (p1[ 1 ] = = p2[ 1 ]): #if frequency is equal return p1[ 0 ] - p2[ 0 ] #return the smaller value return p2[ 1 ] - p1[ 1 ] #return the element with greater frequency # driver code arr = [ 4 , 4 , 5 , 6 , 4 , 2 , 2 , 8 , 5 ] n = len (arr) m = {} for i in range (n): if (arr[i] in m): m[arr[i]] = m[arr[i]] + 1 else : m[arr[i]] = 1 a = [] for x,y in m.items(): a.append([x,y]) #making pair of element and it's frequency a.sort(key = cmp_to_key(compare)) ans = [] for x in a: while (x[ 1 ]): ans.append(x[ 0 ]) x[ 1 ] - = 1 for x in ans: print (x, end = " " ) # This code is contributed by shinjanpatra |
C#
using System; using System.Collections.Generic; class Program { static int Compare(KeyValuePair< int , int > p1, KeyValuePair< int , int > p2) { if (p1.Value == p2.Value) { return p1.Key.CompareTo(p2.Key); } return p2.Value.CompareTo(p1.Value); } static void Main( string [] args) { List< int > arr = new List< int >{4, 4, 5, 6, 4, 2, 2, 8, 5}; Dictionary< int , int > m = new Dictionary< int , int >(); for ( int i = 0; i < arr.Count; i++) { if (!m.ContainsKey(arr[i])) { m[arr[i]] = 0; } m[arr[i]]++; } List<KeyValuePair< int , int >> a = new List<KeyValuePair< int , int >>(); foreach (KeyValuePair< int , int > entry in m) { a.Add(entry); } a.Sort(Compare); List< int > ans = new List< int >(); foreach (KeyValuePair< int , int > x in a) { for ( int i = 0; i < x.Value; i++) { ans.Add(x.Key); } } foreach ( int x in ans) { Console.Write(x + " " ); } } } // This code has been contributed by Prince Kumar |
Javascript
<script> // JavaScript code for the approach function compare(p1, p2) { if (p1[1] == p2[1]) //if frequency is equal { return p1[0] - p2[0]; //return the smaller value } return p2[1] - p1[1]; //return the element with greater frequency } // driver code let arr = [4,4,5,6,4,2,2,8,5]; let n = arr.length; let m = new Map(); for (let i = 0; i < n; i++) { if (m.has(arr[i])){ m.set(arr[i], m.get(arr[i]) + 1); } else m.set(arr[i],1); } let a = []; for (let [x,y] of m) { a.push([x,y]); //making pair of element and it's frequency } a.sort(compare); let ans = []; for (let x of a){ while (x[1]--){ ans.push(x[0]); } } for (let x of ans) { document.write(x, " " ); } // This code is contributed by shinjanpatra </script> |
4 4 4 2 2 5 5 6 8
Time Complexity: O(N*logN) as sort() takes N*logN time (Here N is size of input array). Also, insertion in ordered map takes logN time and since N insertions are done so it also contributes N*logN time. So overall complexity will be O(N*logN).
Using priority_queue:
This approach is based on the idea to use priority_queue with pair of elements as its entry element. The first element of the pair will be frequency of element of the array and second one will be the array element itself. By inserting elements this way in the priority_queue, we will be having highest frequency element at top. So when we pop the priority_queue, we will be having the second entry of the pair which was at top of the priority_queue as our element of the result array. To store the frequency we will be using map as this frequency will be inserted along with element in the priority_queue.
We will be using custom comparator for the priority_queue which sorts the elements in decreasing order of their frequency and by elements value if frequency is equal.
Algorithm:
- Create a class named ‘Compare’ to define a custom comparison operator for a priority queue of pairs of integers.
- In the ‘Compare’ class, define the comparison operator such that pairs are sorted first by their first element in descending order, and then by their second element in ascending order.
- Create a map to store the frequency of each element in the array.
- Traverse through the array and increment the frequency of each element in the map.
- Create a priority queue to store pairs of elements and their frequency in decreasing order.
- Traverse through the map and insert each element and its frequency into the priority queue.
- Declare a new array to store the sorted elements.
- Traverse through the priority queue and insert the elements into the new array based on their frequency.
- Return the resultant array res.
- Output the sorted array.
Below is the implementation of the approach:
C++
// C++ code for the approach #include <bits/stdc++.h> using namespace std; // based on first part in descending and second part in // ascending first basis class Compare { public : bool operator()(pair< int , int > p1, pair< int , int > p2) { if (p1.first == p2.first) { return p1.second > p2.second; } return p1.first < p2.first; } }; // Function to sort the array according // to the frequency of elements vector< int > sortByFrequency( int arr[], int n) { // Declare a map to store the frequency // of each element of the array map< int , int > freqMap; // Traverse through the array for ( int i = 0; i < n; i++) { freqMap[arr[i]]++; } // Declare a priority queue to store the // elements according to their frequency // in decreasing order priority_queue<pair< int , int >, vector<pair< int , int >>, Compare > pq; // Traverse through the map and insert each // element in the priority queue for ( auto it = freqMap.begin(); it != freqMap.end(); it++) { pq.push(make_pair(it->second, it->first)); } // Declare a new array to store the result vector< int > res; // Traverse through the priority queue and // insert the elements in the result array int index = 0; while (!pq.empty()) { int freq = pq.top().first; int element = pq.top().second; pq.pop(); for ( int i = 0; i < freq; i++) { res.push_back( element ); } } return res; } // Driver Code int main() { // Input array int arr[] = { 4, 4, 5, 6, 4, 2, 2, 8, 5 }; int n = sizeof (arr) / sizeof ( int ); // Function Call vector< int > ans = sortByFrequency(arr, n); // Output the sorted array for ( int i = 0; i < n; i++) { cout << ans[i] << " " ; } return 0; } |
Java
import java.util.*; public class Main { public static void main(String[] args) { // Input array int [] arr = { 4 , 4 , 5 , 6 , 4 , 2 , 2 , 8 , 5 }; // Function Call List<Integer> ans = sortByFrequency(arr); // Output the sorted array for ( int element : ans) { System.out.print(element + " " ); } } // Function to sort the array according // to the frequency of elements static List<Integer> sortByFrequency( int [] arr) { // Create a HashMap to count the frequency of each element Map<Integer, Integer> freqMap = new HashMap<>(); // Traverse through the array for ( int element : arr) { freqMap.put(element, freqMap.getOrDefault(element, 0 ) + 1 ); } // Sort the elements by their frequency in descending order List<Map.Entry<Integer, Integer>> sortedElements = new ArrayList<>(freqMap.entrySet()); sortedElements.sort((a, b) -> { int freqComparison = Integer.compare(b.getValue(), a.getValue()); return (freqComparison == 0 ) ? Integer.compare(a.getKey(), b.getKey()) : freqComparison; }); // Declare a new list to store the result List<Integer> res = new ArrayList<>(); // Traverse through the sorted elements and // insert the elements in the result list for (Map.Entry<Integer, Integer> entry : sortedElements) { int element = entry.getKey(); int freq = entry.getValue(); for ( int i = 0 ; i < freq; i++) { res.add(element); } } return res; } } |
Python3
from collections import Counter # Function to sort the array according # to the frequency of elements def sort_by_frequency(arr): # Create a Counter to count the frequency of each element freq_map = Counter(arr) # Sort the elements by their frequency in descending order sorted_elements = sorted (freq_map.items(), key = lambda x: ( - x[ 1 ], x[ 0 ])) # Declare a new list to store the result res = [] # Traverse through the sorted elements and # insert the elements in the result list for element, freq in sorted_elements: res.extend([element] * freq) return res # Driver Code if __name__ = = "__main__" : # Input array arr = [ 4 , 4 , 5 , 6 , 4 , 2 , 2 , 8 , 5 ] # Function Call ans = sort_by_frequency(arr) # Output the sorted array for element in ans: print (element, end = " " ) |
C#
using System; using System.Collections.Generic; using System.Linq; class Program { // Function to sort the array according // to the frequency of elements static List< int > SortByFrequency(List< int > arr) { // Create a Dictionary to count the frequency of each element Dictionary< int , int > freqMap = new Dictionary< int , int >(); // Populate the frequency map foreach ( int element in arr) { if (freqMap.ContainsKey(element)) { freqMap[element]++; } else { freqMap[element] = 1; } } // Sort the elements by their frequency in descending order var sortedElements = freqMap.OrderByDescending(x => x.Value).ThenBy(x => x.Key); // Declare a new list to store the result List< int > res = new List< int >(); // Traverse through the sorted elements and // insert the elements in the result list foreach ( var kvp in sortedElements) { int element = kvp.Key; int freq = kvp.Value; res.AddRange(Enumerable.Repeat(element, freq)); } return res; } static void Main( string [] args) { // Input array List< int > arr = new List< int > { 4, 4, 5, 6, 4, 2, 2, 8, 5 }; // Function Call List< int > ans = SortByFrequency(arr); // Output the sorted array foreach ( int element in ans) { Console.Write(element + " " ); } } } |
Javascript
function sortByFrequency(arr) { // Create a Map to count the frequency of each element const freqMap = new Map(); // Traverse through the array for (const element of arr) { freqMap.set(element, (freqMap.get(element) || 0) + 1); } // Sort the elements by their frequency in descending order const sortedElements = [...freqMap.entries()].sort((a, b) => { const freqComparison = b[1] - a[1]; return freqComparison === 0 ? a[0] - b[0] : freqComparison; }); // Create a new array to store the result const res = []; // Traverse through the sorted elements and insert the elements in the result array for (const [element, freq] of sortedElements) { for (let i = 0; i < freq; i++) { res.push(element); } } return res; } // Input array const arr = [4, 4, 5, 6, 4, 2, 2, 8, 5]; // Function call const ans = sortByFrequency(arr); // Output the sorted array console.log(ans.join( ' ' )); |
4 4 4 2 2 5 5 6 8
Time Complexity: O(n * log2n) where n is the size of input array. This is because priority_queue insertion takes (n * log2n) time as n elements are inserted.
Space Complexity: O(n) where n is size of input array. This is because freqMap map and res vector has been created.
Contact Us