Given an unsorted array. The task is to calculate the cumulative frequency of each element of the array using a count array.
Examples:
Input : arr[] = [1, 2, 2, 1, 3, 4]
Output :1->2
2->4
3->5
4->6
Input : arr[] = [1, 1, 1, 2, 2, 2]
Output :1->3
2->6
A simple solution is to use two nested loops. The outer loop picks an element from left to right that is not visited. The inner loop counts its occurrences and marks occurrences as visited. The time complexity of this solution is O(n*n) and the auxiliary space required is O(n).
A better solution is to use sorting. We sort the array so that the same elements come together. After sorting, we linearly traverse elements and count their frequencies.
An efficient solution is to use hashing. Insert the element and its frequency in a set of pairs. As the set stores unique values in a sorted order, it will store all the elements with their frequencies in a sorted order. Iterate in the set and print the frequencies by adding the previous ones at every step.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void countFreq( int a[], int n)
{
map< int , int > m;
for ( int i = 0; i < n; i++) {
m[a[i]]++;
}
int cumul = 0;
for ( auto v : m) {
cout << v.first << " " << v.second + cumul
<< endl;
cumul += v.second;
}
}
int main()
{
int arr[] = { 1, 3, 2, 4, 2, 1 };
int n = sizeof (arr) / sizeof (arr[0]);
countFreq(arr, n);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static void countFreq( int [] a, int n)
{
HashMap<Integer,
Integer> hm = new HashMap<>();
for ( int i = 0 ; i < n; i++)
hm.put(a[i], hm.get(a[i]) == null ?
1 : hm.get(a[i]) + 1 );
SortedMap<Integer, Integer> st = new TreeMap<>();
for (HashMap.Entry<Integer,
Integer> x : hm.entrySet())
{
st.put(x.getKey(), x.getValue());
}
int cumul = 0 ;
for (SortedMap.Entry<Integer,
Integer> x : st.entrySet())
{
cumul += x.getValue();
System.out.println(x.getKey() + " " + cumul);
}
}
public static void main(String[] args)
{
int [] a = { 1 , 3 , 2 , 4 , 2 , 1 };
int n = a.length;
countFreq(a, n);
}
}
|
Python3
def countFreq(a, n):
hm = {}
for i in range ( 0 , n):
hm[a[i]] = hm.get(a[i], 0 ) + 1
st = set ()
for x in hm:
st.add((x, hm[x]))
cumul = 0
for x in sorted (st):
cumul + = x[ 1 ]
print (x[ 0 ], cumul)
if __name__ = = "__main__" :
a = [ 1 , 3 , 2 , 4 , 2 , 1 ]
n = len (a)
countFreq(a, n)
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG{
static void countFreq( int [] a, int n)
{
Dictionary< int ,
int > hm = new Dictionary< int ,
int >();
for ( int i = 0; i < n; i++)
{
if (hm.ContainsKey(a[i]))
{
hm[a[i]]++;
}
else
{
hm[a[i]] = 1;
}
}
int cumul = 0;
foreach (KeyValuePair< int ,
int > x in hm.OrderBy(key => key.Key))
{
cumul += x.Value;
Console.Write(x.Key + " " + cumul + "\n" );
}
}
public static void Main( string [] args)
{
int [] a = { 1, 3, 2, 4, 2, 1 };
int n = a.Length;
countFreq(a, n);
}
}
|
Javascript
<script>
function countFreq(a,n)
{
let hm = new Map();
for (let i = 0; i < n; i++)
hm.set(a[i], hm.get(a[i]) == null ?
1 : hm.get(a[i]) + 1);
let st = new Set();
for (let [key, value] of hm.entries())
{
st.add([key, value]);
}
st=[...st.entries()].sort()
let cumul = 0;
for (let [key, value] of st.entries())
{
cumul += value[1][1];
document.write(value[1][0] + " " + cumul+ "<br>" );
}
}
let a=[1, 3, 2, 4, 2, 1];
let n = a.length;
countFreq(a, n);
</script>
|
Time Complexity: O(n log n), where n is the size of the given array
Auxiliary Space: O(n), as extra space of size n is used to create a map
What if we need frequencies of elements according to the order of the first occurrence?
For example, an array [2, 4, 1, 2, 1, 3, 4], the frequency of 2 should be printed first, then of 4, then 1, and finally 3.
Approach: Hash the count of occurrences of an element. Traverse in the array and print the cumulative frequency. Once the element and its cumulative frequency has been printed, hash the occurrence of that element as 0 so that it not printed again if it appears in the latter half of array while traversal.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void countFreq( int a[], int n)
{
unordered_map< int , int > hm;
for ( int i=0; i<n; i++)
hm[a[i]]++;
int cumul = 0;
for ( int i=0;i<n;i++)
{
cumul += hm[a[i]];
if (hm[a[i]])
{
cout << a[i] << "->" << cumul << endl;
}
hm[a[i]]=0;
}
}
int main()
{
int a[] = {1, 3, 2, 4, 2, 1};
int n = sizeof (a)/ sizeof (a[0]);
countFreq(a, n);
return 0;
}
|
Java
class GFG
{
static void countFreq( int a[], int n)
{
int hm[] = new int [n];
for ( int i = 0 ; i < n; i++)
hm[a[i]]++;
int cumul = 0 ;
for ( int i = 0 ; i < n; i++)
{
cumul += hm[a[i]];
if (hm[a[i]] != 0 )
{
System.out.println(a[i] + "->" + cumul);
}
hm[a[i]] = 0 ;
}
}
public static void main(String[] args)
{
int a[] = { 1 , 3 , 2 , 4 , 2 , 1 };
int n = a.length;
countFreq(a, n);
}
}
|
Python3
def countFreq(a, n):
hm = dict ()
for i in range (n):
hm[a[i]] = hm.get(a[i], 0 ) + 1
cumul = 0
for i in range (n):
cumul + = hm[a[i]]
if (hm[a[i]] > 0 ):
print (a[i], "->" , cumul)
hm[a[i]] = 0
a = [ 1 , 3 , 2 , 4 , 2 , 1 ]
n = len (a)
countFreq(a, n)
|
C#
using System;
class GFG
{
static void countFreq( int []a, int n)
{
int []hm = new int [n];
for ( int i = 0; i < n; i++)
hm[a[i]]++;
int cumul = 0;
for ( int i = 0; i < n; i++)
{
cumul += hm[a[i]];
if (hm[a[i]] != 0)
{
Console.WriteLine(a[i] + "->" + cumul);
}
hm[a[i]] = 0;
}
}
public static void Main(String[] args)
{
int []a = {1, 3, 2, 4, 2, 1};
int n = a.Length;
countFreq(a, n);
}
}
|
Javascript
<script>
function countFreq(a,n) {
let hm = new Array(n);
for (let i=0;i<hm.length;i++)
{
hm[i]=0;
}
for (let i = 0; i < n; i++)
hm[a[i]]++;
let cumul = 0;
for (let i = 0; i < n; i++)
{
cumul += hm[a[i]];
if (hm[a[i]] != 0)
{
document.write(a[i] + "->" + cumul+ "<br>" );
}
hm[a[i]] = 0;
}
}
let a=[1, 3, 2, 4, 2, 1];
let n = a.length;
countFreq(a, n);
</script>
|
Output:
1->2
3->3
2->5
4->6
Time Complexity: O(n), where n is the size of the given array
Auxiliary Space: O(n), as extra space of size n is used to create a map
If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
07 Oct, 2022
Like Article
Save Article