Frequency Measuring Techniques for Competitive Programming
Measuring the frequency of elements in an array is a really handy skill and is required a lot of competitive coding problems. We, in a lot of problems, are required to measure the frequency of various elements like numbers, alphabets, symbols, etc. as a part of our problem.
Examples:
Input: arr[] = {10, 20, 20, 10, 10, 20, 5, 20}
Output: 10 3
20 4
5 1
Input: arr[] = {10, 20, 20}
Output: 10 2
20 1
Naive method: We run two loops. For every item count number of times, it occurs. To avoid duplicate printing, keep track of processed items.
Implementation:
C++
Java
import java.util.*;
class GFG
{
static void countFreq( int arr[], int n)
{
boolean []visited = new boolean [n];
for ( int i = 0 ; i < n; i++)
{
if (visited[i] == true )
continue ;
int count = 1 ;
for ( int j = i + 1 ; j < n; j++)
{
if (arr[i] == arr[j])
{
visited[j] = true ;
count++;
}
}
System.out.println(arr[i] + " " + count);
}
}
public static void main(String[] args)
{
int arr[] = { 10 , 20 , 20 , 10 , 10 , 20 , 5 , 20 };
int n = arr.length;
countFreq(arr, n);
}
}
|
Python3
C#
Javascript
<script>
function countFreq(arr, n)
{
let visited = new Array(n);
visited.fill( false );
for (let i = 0; i < n; i++) {
if (visited[i] == true )
continue ;
let count = 1;
for (let j = i + 1; j < n; j++) {
if (arr[i] == arr[j]) {
visited[j] = true ;
count++;
}
}
document.write(arr[i] + " " + count + "</br>" );
}
}
let arr = [ 10, 20, 20, 10, 10, 20, 5, 20 ];
let n = arr.length;
countFreq(arr, n);
</script>
|
Time Complexity: O(n*n)
Auxiliary Space: O(n)
Optimized methods :
Measuring frequencies when elements are limited by value: If our input array has small values, we can use array elements as index in a count array and increment count. In below example, elements are maximum 10.
Input : arr[] = {5, 5, 6, 6, 5, 6, 1, 2, 3, 10, 10}
limit = 10
Output : 1 1
2 1
3 1
5 3
6 3
10 2
Implementation:
C++
Java
Python3
C#
Javascript
Output
1 1
2 1
3 1
5 3
6 3
10 2
Time Complexity: O(n+k) where n is the size of the input array and k is the limit value.
Auxiliary Space: O(k).
Implementation:
C++
Java
Python3
C#
Javascript
<script>
let limit = 255;
function countFreq(str)
{
let count= new Array(limit + 1);
for (let i=0;i<count.length;i++)
{
count[i]=0;
}
for (let i = 0; i < str.length; i++)
count[str[i].charCodeAt(0)]++;
for (let i = 0; i <= limit; i++)
{ if (count[i] > 0)
document.write(String.fromCharCode(i) + " " + count[i]+ "<br>" );
}
}
let str = "GeeksforGeeks" ;
countFreq(str);
</script>
|
Output
G 2
e 4
f 1
k 2
o 1
r 1
s 2
Measuring frequencies when elements are in limited range: For example, consider a string containing only upper case alphabets. Elements of string are limited in range from ‘A’ to ‘Z’. The idea is to subtract smallest element (‘A’ in this example) to get the index of the element.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
const int limit = 25;
void countFreq(string str)
{
vector< int > count(limit+1, 0);
for ( int i = 0; i < str.length(); i++)
count[str[i] - 'A' ]++;
for ( int i = 0; i <= limit; i++)
if (count[i] > 0)
cout << ( char )(i + 'A' ) << " " << count[i] << endl;
}
int main()
{
string str = "GEEKSFORGEEKS" ;
countFreq(str);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int limit = 25 ;
static void countFreq(String str)
{
int []count = new int [limit + 1 ];
for ( int i = 0 ; i < str.length(); i++)
count[str.charAt(i) - 'A' ]++;
for ( int i = 0 ; i <= limit; i++)
if (count[i] > 0 )
System.out.println(( char )(i + 'A' ) +
" " + count[i]);
}
public static void main(String[] args)
{
String str = "GEEKSFORGEEKS" ;
countFreq(str);
}
}
|
Python3
limit = 25 ;
def countFreq( str ):
count = [ 0 for i in range (limit + 1 )]
for i in range ( len ( str )):
count[ ord ( str [i]) - ord ( 'A' )] + = 1
for i in range (limit + 1 ):
if (count[i] > 0 ):
print ( chr (i + ord ( 'A' )), count[i])
if __name__ = = '__main__' :
str = "GEEKSFORGEEKS" ;
countFreq( str );
|
C#
using System;
class GFG
{
static int limit = 25;
static void countFreq(String str)
{
int []count = new int [limit + 1];
for ( int i = 0; i < str.Length; i++)
count[str[i] - 'A' ]++;
for ( int i = 0; i <= limit; i++)
if (count[i] > 0)
Console.WriteLine(( char )(i + 'A' ) +
" " + count[i]);
}
public static void Main(String[] args)
{
String str = "GEEKSFORGEEKS" ;
countFreq(str);
}
}
|
Javascript
<script>
let limit = 25;
function countFreq(str)
{
let count = new Array(limit + 1);
for (let i=0;i<limit+1;i++)
{
count[i]=0;
}
for (let i = 0; i < str.length; i++)
count[str[i].charCodeAt(0) - 'A' .charCodeAt(0)]++;
for (let i = 0; i <= limit; i++)
if (count[i] > 0)
document.write(String.fromCharCode(i + 'A' .charCodeAt(0)) +
" " + count[i]+ "<br>" );
}
let str = "GEEKSFORGEEKS" ;
countFreq(str);
</script>
|
Output
E 4
F 1
G 2
K 2
O 1
R 1
S 2
Measuring frequencies if no range and no limit: The idea is to use hashing (unordered_map in C++ and HashMap in Java) to get frequencies.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
void countFreq( int arr[], int n)
{
unordered_map< int , int > mp;
for ( int i = 0; i < n; i++)
mp[arr[i]]++;
for ( auto x : mp)
cout << x.first << " " << x.second << endl;
}
int main()
{
int arr[] = { 10, 20, 20, 10, 10, 20, 5, 20 };
int n = sizeof (arr) / sizeof (arr[0]);
countFreq(arr, n);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static void countFreq( int arr[], int n)
{
HashMap<Integer,
Integer>mp = new HashMap<Integer,
Integer>();
for ( int i = 0 ; i < n; i++)
{
if (mp.containsKey(arr[i]))
{
mp.put(arr[i], mp.get(arr[i]) + 1 );
}
else
{
mp.put(arr[i], 1 );
}
}
for (Map.Entry<Integer,
Integer> entry : mp.entrySet())
System.out.println(entry.getKey() + " " +
entry.getValue());
}
public static void main(String[] args)
{
int arr[] = { 10 , 20 , 20 , 10 , 10 , 20 , 5 , 20 };
int n = arr.length;
countFreq(arr, n);
}
}
|
Python3
def countFreq(arr, n):
mp = {}
for i in range (n):
if arr[i] in mp:
mp[arr[i]] + = 1
else :
mp[arr[i]] = 1
for x in sorted (mp):
print (x, mp[x])
arr = [ 10 , 20 , 20 , 10 , 10 , 20 , 5 , 20 ]
n = len (arr)
countFreq(arr, n)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static void countFreq( int []arr, int n)
{
Dictionary< int ,
int > mp = new Dictionary< int ,
int >();
for ( int i = 0 ; i < n; i++)
{
if (mp.ContainsKey(arr[i]))
{
var val = mp[arr[i]];
mp.Remove(arr[i]);
mp.Add(arr[i], val + 1);
}
else
{
mp.Add(arr[i], 1);
}
}
foreach (KeyValuePair< int , int > entry in mp)
Console.WriteLine(entry.Key + " " +
entry.Value);
}
public static void Main(String[] args)
{
int []arr = { 10, 20, 20, 10,
10, 20, 5, 20 };
int n = arr.Length;
countFreq(arr, n);
}
}
|
Javascript
<script>
function countFreq(arr, n)
{
let mp = new Map();
for (let i = 0 ; i < n; i++)
{
if (mp.has(arr[i]))
{
mp.set(arr[i], mp.get(arr[i]) + 1);
}
else
{
mp.set(arr[i], 1);
}
}
for (let [key, value] of mp.entries())
document.write(key + " " +
value+ "<br>" );
}
let arr=[10, 20, 20, 10, 10, 20, 5, 20];
let n = arr.length;
countFreq(arr, n);
</script>
|
Complexity Analysis:
- Time Complexity : O(n)
- Auxiliary Space : O(n)
In above efficient solution, how to print elements in same order as they appear in input?
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
void countFreq( int arr[], int n)
{
unordered_map< int , int > mp;
for ( int i = 0; i < n; i++)
mp[arr[i]]++;
for ( int i = 0; i < n; i++) {
if (mp[arr[i]] != -1)
{
cout << arr[i] << " " << mp[arr[i]] << endl;
mp[arr[i]] = -1;
}
}
}
int main()
{
int arr[] = { 10, 20, 20, 10, 10, 20, 5, 20 };
int n = sizeof (arr) / sizeof (arr[0]);
countFreq(arr, n);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static void countFreq( int arr[], int n)
{
HashMap<Integer,
Integer> mp = new HashMap<Integer,
Integer>();
for ( int i = 0 ; i < n; i++)
{
if (mp.containsKey(arr[i]))
{
mp.put(arr[i], mp.get(arr[i]) + 1 );
}
else
{
mp.put(arr[i], 1 );
}
}
for ( int i = 0 ; i < n; i++)
{
if (mp.get(arr[i]) != - 1 )
{
System.out.println(arr[i] + " " +
mp.get(arr[i]));
mp. put(arr[i], - 1 );
}
}
}
public static void main(String[] args)
{
int arr[] = { 10 , 20 , 20 , 10 , 10 , 20 , 5 , 20 };
int n = arr.length;
countFreq(arr, n);
}
}
|
Python3
def countFreq(arr, n):
mp = {}
for i in range (n):
if arr[i] not in mp:
mp[arr[i]] = 1
else :
mp[arr[i]] + = 1
for i in range (n):
if (mp[arr[i]] ! = - 1 ):
print (arr[i], mp[arr[i]])
mp[arr[i]] = - 1
arr = [ 10 , 20 , 20 , 10 , 10 , 20 , 5 , 20 ]
n = len (arr)
countFreq(arr, n)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static void countFreq( int []arr, int n)
{
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);
}
}
for ( int i = 0; i < n; i++)
{
if (mp[arr[i]] != -1)
{
Console.WriteLine(arr[i] + " " +
mp[arr[i]]);
mp[arr[i]] = - 1;
}
}
}
public static void Main(String[] args)
{
int []arr = { 10, 20, 20, 10,
10, 20, 5, 20 };
int n = arr.Length;
countFreq(arr, n);
}
}
|
Javascript
<script>
function countFreq(arr, n)
{
let mp = new Map();
for (let i = 0 ; i < n; i++)
{
if (mp.has(arr[i]))
{
mp.set(arr[i], mp.get(arr[i]) + 1);
}
else
{
mp.set(arr[i], 1);
}
}
for (let i = 0; i < n; i++)
{
if (mp.get(arr[i]) != -1)
{
document.write(arr[i] + " " +
mp.get(arr[i]) + "<br>" );
mp.set(arr[i], -1);
}
}
}
let arr = [ 10, 20, 20, 10, 10, 20, 5, 20 ];
let n = arr.length;
countFreq(arr, n);
</script>
|
Complexity Analysis
- Time Complexity : O(n)
- Auxiliary Space : O(n)
In Java, we can get elements in same order using LinkedHashMap. Therefore we do not need an extra loop.
Lot of problems are based on frequency measurement and will be a cheesecake if we know how to calculate frequency of various elements in a given array. For example try the given below problems which are based on frequency measurement:
- Anagrams
- Sorting Elements of an Array by Frequency
- Single Number
Last Updated :
15 Jan, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...