Find frequency of each element in a limited range array in less than O(n) time
Last Updated :
18 Sep, 2023
Given a sorted array arr[] of positive integers, the task is to find the frequency for each element in the array. Assume all elements in the array are less than some constant M
Note: Do this without traversing the complete array. i.e. expected time complexity is less than O(n)
Examples:
Input: arr[] = [1, 1, 1, 2, 3, 3, 5, 5, 8, 8, 8, 9, 9, 10]
Output:
Element 1 occurs 3 times
Element 2 occurs 1 times
Element 3 occurs 2 times
Element 5 occurs 2 times
Element 8 occurs 3 times
Element 9 occurs 2 times
Element 10 occurs 1 times
Input: arr[] = [2, 2, 6, 6, 7, 7, 7, 11]
Output:
Element 2 occurs 2 times
Element 6 occurs 2 times
Element 7 occurs 3 times
Element 11 occurs 1 times
Frequency of each element in a limited range array using linear search:
To solve the problem follow the below idea:
Traverse the input array and increment the frequency of the element if the current element and the previous element are the same, otherwise reset the frequency and print the element and its frequency
Follow the given steps to solve the problem:
- Initialize frequency to 1 and index to 1.
- Traverse the array from the index position and check if the current element is equal to the previous element.
- If yes, increment the frequency and index and repeat step 2. Otherwise, print the element and its frequency and repeat step 2.
- At last(corner case), print the last element and its frequency.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void findFrequencies( int ele[], int n)
{
int freq = 1;
int idx = 1;
int element = ele[0];
while (idx < n) {
if (ele[idx - 1] == ele[idx]) {
freq++;
idx++;
}
else {
cout << element << " " << freq << endl;
element = ele[idx];
idx++;
freq = 1;
}
}
cout << element << " " << freq;
}
int main()
{
cout << "---frequencies in a sorted array----" << endl;
int arr[]
= { 10, 20, 30, 30, 30, 40, 50, 50, 50, 50, 70 };
int n = sizeof (arr) / sizeof (arr[0]);
findFrequencies(arr, n);
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static void findFrequencies( int [] ele, int n)
{
int freq = 1 ;
int idx = 1 ;
int element = ele[ 0 ];
while (idx < n) {
if (ele[idx - 1 ] == ele[idx]) {
freq++;
idx++;
}
else {
System.out.println(element + " " + freq);
element = ele[idx];
idx++;
freq = 1 ;
}
}
System.out.println(element + " " + freq);
}
public static void main(String[] args)
{
System.out.println(
"---frequencies in a sorted array----" );
int [] arr = { 10 , 20 , 30 , 30 , 30 , 40 ,
50 , 50 , 50 , 50 , 70 };
int n = arr.length;
findFrequencies(arr, n);
}
}
|
Python3
def findFrequencies(ele, n):
freq = 1
idx = 1
element = ele[ 0 ]
while (idx < n):
if (ele[idx - 1 ] = = ele[idx]):
freq + = 1
idx + = 1
else :
print (element, " " , freq)
element = ele[idx]
idx + = 1
freq = 1
print (element, " " , freq)
if __name__ = = "__main__" :
print ( "---frequencies in a sorted array----" )
arr = [ 10 , 20 , 30 , 30 , 30 , 40 , 50 , 50 , 50 , 50 , 70 ]
n = len (arr)
findFrequencies(arr, n)
|
C#
using System;
class GFG {
public static void findFrequencies( int [] ele)
{
int freq = 1;
int idx = 1;
int element = ele[0];
while (idx < ele.Length) {
if (ele[idx - 1] == ele[idx]) {
freq++;
idx++;
}
else {
Console.WriteLine(element + " " + freq);
element = ele[idx];
idx++;
freq = 1;
}
}
Console.WriteLine(element + " " + freq);
}
public static void Main(String[] args)
{
Console.WriteLine(
"---frequencies in a sorted array----" );
findFrequencies( new int [] { 10, 20, 30, 30, 30, 40,
50, 50, 50, 50, 70 });
}
}
|
Javascript
<script>
function void findFrequencies(ele)
{
var freq = 1;
var idx = 1;
var element = ele[0];
while (idx < ele.length)
{
if (ele[idx - 1] == ele[idx]) {
freq++;
idx++;
}
else
{
document.write(element + " " + freq);
element = ele[idx];
idx++;
freq = 1;
}
}
document.write(element + " " + freq);
}
document.write(
"---frequencies in a sorted array----" );
findFrequencies( new var [] { 10, 20, 30, 30, 30, 40,
50, 50, 50, 50, 70 });
</script>
|
Output
---frequencies in a sorted array----
10 1
20 1
30 3
40 1
50 4
70 1
Time Complexity: O(N)
Auxiliary Space: O(1)
Frequency of each element in a limited range array using Hash-Map:
To solve the problem follow the below idea:
The idea is to traverse the input array and for each distinct element of the array, store its frequency in a HashMap, and finally print the HashMap.
Follow the given steps to solve the problem:
- Create a HashMap to map the frequency to the element, i.e to store the element-frequency pair.
- Traverse the array from start to end.
- For each element in the array update the frequency, i.e hm[array[i]]++
- Traverse the HashMap and print the element frequency pair
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void findFrequency( int arr[], int n)
{
unordered_map< int , int > mp;
for ( int i = 0; i < n; i++) {
mp[arr[i]]++;
}
for ( auto i : mp) {
cout << "Element " << i.first << " occurs "
<< i.second << " times" << endl;
}
}
int main()
{
int arr[]
= { 1, 1, 1, 2, 3, 3, 5, 5, 8, 8, 8, 9, 9, 10 };
int n = sizeof (arr) / sizeof (arr[0]);
findFrequency(arr, n);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static void findFrequency( int [] arr, int n)
{
Map<Integer, Integer> mp
= new HashMap<Integer, Integer>();
for ( int i = 0 ; i < n; i++) {
if (!mp.containsKey(arr[i]))
mp.put(arr[i], 0 );
mp.put(arr[i], mp.get(arr[i]) + 1 );
}
for (Map.Entry<Integer, Integer> kvp :
mp.entrySet()) {
System.out.println( "Element " + kvp.getKey()
+ " occurs " + kvp.getValue()
+ " times" );
}
}
public static void main(String[] args)
{
int [] arr
= { 1 , 1 , 1 , 2 , 3 , 3 , 5 , 5 , 8 , 8 , 8 , 9 , 9 , 10 };
int n = arr.length;
findFrequency(arr, n);
}
}
|
Python3
def findFrequency(arr, n):
mp = {}
for i in range (n):
if arr[i] not in mp:
mp[arr[i]] = 0
mp[arr[i]] + = 1
for i in mp:
print ( "Element" , i, "occurs" , mp[i], "times" )
if __name__ = = "__main__" :
arr = [ 1 , 1 , 1 , 2 , 3 , 3 , 5 , 5 , 8 , 8 , 8 , 9 , 9 , 10 ]
n = len (arr)
findFrequency(arr, n)
|
C#
using System;
using System.Collections.Generic;
class GFG {
static void findFrequency( 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]] = 0;
mp[arr[i]]++;
}
foreach (KeyValuePair< int , int > kvp in mp)
Console.WriteLine( "Element " + kvp.Key
+ " occurs " + kvp.Value
+ " times" );
}
public static void Main()
{
int [] arr
= { 1, 1, 1, 2, 3, 3, 5, 5, 8, 8, 8, 9, 9, 10 };
int n = arr.Length;
findFrequency(arr, n);
}
}
|
Javascript
<script>
function findFrequency(arr, n)
{
let mp = new Map();
for (let i = 0; i < n; i++)
{
if (!mp.has(arr[i]))
mp.set(arr[i],0);
mp.set(arr[i], mp.get(arr[i]) + 1);
}
for (let [key, value] of mp.entries())
{
document.write( "Element " + key +
" occurs " + value +
" times<br>" );
}
}
let arr = [ 1, 1, 1, 2, 3, 3, 5,
5, 8, 8, 8, 9, 9, 10 ];
let n = arr.length;
findFrequency(arr, n);
</script>
|
Output
Element 10 occurs 1 times
Element 9 occurs 2 times
Element 8 occurs 3 times
Element 5 occurs 2 times
Element 3 occurs 2 times
Element 2 occurs 1 times
Element 1 occurs 3 times
Time Complexity: O(N), only one traversal of the array is needed.
Auxiliary Space: O(N), to store the elements in the HashMap O(N) extra space is needed.
Frequency of each element in a limited range array using binary search:
The problem can be solved in less than O(n) time if all its elements are sorted, i.e. if similar elements exist in the array then the elements are in a contiguous subarray or it can be said that if the ends of a subarray are the same then all the elements inside the subarray are equal. So the count of that element is the size of the subarray and all the elements of that subarray need not be counted.
Follow the given steps to solve the problem:
- Create a HashMap (hm) to store the frequency of elements.
- Create a recursive function that accepts an array and size.
- Check if the first element of the array is equal to the last element. If equal then all the elements are the same and update the frequency by hm[array[0]+=size
- Else divide the array into two equal halves and call the function recursively for both halves.
- Traverse the hashmap and print the element frequency pair.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void findFrequencyUtil( int arr[], int low, int high,
vector< int >& freq)
{
if (arr[low] == arr[high]) {
freq[arr[low]] += high - low + 1;
}
else {
int mid = (low + high) / 2;
findFrequencyUtil(arr, low, mid, freq);
findFrequencyUtil(arr, mid + 1, high, freq);
}
}
void findFrequency( int arr[], int n)
{
vector< int > freq(arr[n - 1] + 1, 0);
findFrequencyUtil(arr, 0, n - 1, freq);
for ( int i = 0; i <= arr[n - 1]; i++)
if (freq[i] != 0)
cout << "Element " << i << " occurs " << freq[i]
<< " times" << endl;
}
int main()
{
int arr[]
= { 1, 1, 1, 2, 3, 3, 5, 5, 8, 8, 8, 9, 9, 10 };
int n = sizeof (arr) / sizeof (arr[0]);
findFrequency(arr, n);
return 0;
}
|
Java
import java.util.*;
class GFG {
static void findFrequencyUtil( int arr[], int low,
int high, int [] freq)
{
if (arr[low] == arr[high]) {
freq[arr[low]] += high - low + 1 ;
}
else {
int mid = (low + high) / 2 ;
findFrequencyUtil(arr, low, mid, freq);
findFrequencyUtil(arr, mid + 1 , high, freq);
}
}
static void findFrequency( int arr[], int n)
{
int [] freq = new int [arr[n - 1 ] + 1 ];
findFrequencyUtil(arr, 0 , n - 1 , freq);
for ( int i = 0 ; i <= arr[n - 1 ]; i++)
if (freq[i] != 0 )
System.out.println( "Element " + i
+ " occurs " + freq[i]
+ " times" );
}
public static void main(String[] args)
{
int arr[]
= { 1 , 1 , 1 , 2 , 3 , 3 , 5 , 5 , 8 , 8 , 8 , 9 , 9 , 10 };
int n = arr.length;
findFrequency(arr, n);
}
}
|
Python3
def findFrequencyUtil(arr, low, high, freq):
if (arr[low] = = arr[high]):
freq[arr[low]] + = high - low + 1
else :
mid = int ((low + high) / 2 )
findFrequencyUtil(arr, low, mid, freq)
findFrequencyUtil(arr, mid + 1 , high, freq)
def findFrequency(arr, n):
freq = [ 0 for i in range (n - 1 + 1 )]
findFrequencyUtil(arr, 0 , n - 1 , freq)
for i in range ( 0 , arr[n - 1 ] + 1 , 1 ):
if (freq[i] ! = 0 ):
print ( "Element" , i, "occurs" ,
freq[i], "times" )
if __name__ = = '__main__' :
arr = [ 1 , 1 , 1 , 2 , 3 , 3 , 5 ,
5 , 8 , 8 , 8 , 9 , 9 , 10 ]
n = len (arr)
findFrequency(arr, n)
|
C#
using System;
class GFG {
static void findFrequencyUtil( int [] arr, int low,
int high, int [] freq)
{
if (arr[low] == arr[high]) {
freq[arr[low]] += high - low + 1;
}
else {
int mid = (low + high) / 2;
findFrequencyUtil(arr, low, mid, freq);
findFrequencyUtil(arr, mid + 1, high, freq);
}
}
static void findFrequency( int [] arr, int n)
{
int [] freq = new int [arr[n - 1] + 1];
findFrequencyUtil(arr, 0, n - 1, freq);
for ( int i = 0; i <= arr[n - 1]; i++)
if (freq[i] != 0)
Console.WriteLine( "Element " + i
+ " occurs " + freq[i]
+ " times" );
}
public static void Main(String[] args)
{
int [] arr
= { 1, 1, 1, 2, 3, 3, 5, 5, 8, 8, 8, 9, 9, 10 };
int n = arr.Length;
findFrequency(arr, n);
}
}
|
Javascript
<script>
function findFrequencyUtil(arr, low, high, freq)
{
if (arr[low] == arr[high])
{
freq[arr[low]] += high - low + 1;
}
else
{
let mid = Math.floor((low + high) / 2);
findFrequencyUtil(arr, low, mid, freq);
findFrequencyUtil(arr, mid + 1, high, freq);
}
}
function findFrequency(arr, n)
{
let freq = new Array(arr[n - 1] + 1);
for (let i = 0; i < arr[n - 1] + 1; i++)
{
freq[i] = 0;
}
findFrequencyUtil(arr, 0, n - 1, freq);
for (let i = 0; i <= arr[n - 1]; i++)
if (freq[i] != 0)
document.write( "Element " + i + " occurs " + freq[i] + " times<br>" );
}
let arr = [1, 1, 1, 2, 3, 3, 5,
5, 8, 8, 8, 9, 9, 10 ];
let n = arr.length;
findFrequency(arr, n);
</script>
|
Output
Element 1 occurs 3 times
Element 2 occurs 1 times
Element 3 occurs 2 times
Element 5 occurs 2 times
Element 8 occurs 3 times
Element 9 occurs 2 times
Element 10 occurs 1 times
Time Complexity: O(m log N). Where m is the number of distinct elements in the array of size N. Since m <= M (a constant) (elements are in a limited range), the time complexity of this solution is O(log N)
Auxiliary Space: O(N). To store the elements in the HashMap O(n) extra space is needed.
Frequency of each element in a limited range array using the input array as a Hash-Map:
In this method, we use the same array as the hash map by modifying its content:
Dry run of this approach:
Input: arr = { 1, 1, 1, 2, 3, 3, 5, 5, 8, 8, 8, 9, 9, 10 };
Step 1: Subtract 1 from each element of the array
arr = {0 ,0 ,0 ,1 ,2 ,2 ,4 ,4 ,7 ,7 ,7 ,8 ,8 ,9 }
Step 2: Add n to the index at which the current array element points.
for example :-
when i=0, arr[arr[0]%n] = 0 adding n to the arr[0], arr[0] = 14;
when i=1, arr[arr[1]%n] = 14 adding n to arr[0] ,arr[0] = 28;
Similarly finding the modified array in the same way we will get array as
arr = {42 ,14 ,28 ,1 ,30, 2, 4, 46, 35, 21, 7, 8, 8, 9}
Step 3: Now in step 2 if you have noticed we added the n value to the index at which a particular element points to. So if we have more than one time have a element that point to the same index then in that case the division of the modified number with the n gives us the frequency of the number.
for example
at i=0; arr[0] =42; arr[0] / n = 3 it means that 0 appeared three times in the modified array as you can see in the arr of step 1.
at i=1; arr[1] =14; arr[1]/14 = 1 it means that 1 appeared once in the modified array as you can see in the arr of step 1 .
and similarly for other values we can calculate.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void findFrequency( int input[], int n)
{
for ( int i = 0; i < n; i++)
input[i]--;
for ( int i = 0; i < n; i++)
input[input[i] % n] += n;
for ( int i = 0; i < n; i++) {
if (input[i] / n)
cout << "Element " << (i + 1) << " occurs "
<< input[i] / n << " times" << endl;
input[i] = input[i] % n + 1;
}
}
int main()
{
int arr[]
= { 1, 1, 1, 2, 3, 3, 5, 5, 8, 8, 8, 9, 9, 10 };
int n = sizeof (arr) / sizeof (arr[0]);
findFrequency(arr, n);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static void findFrequency( int [] input, int n)
{
for ( int i = 0 ; i < n; i++)
input[i]--;
for ( int i = 0 ; i < n; i++)
input[input[i] % n] += n;
for ( int i = 0 ; i < n; i++) {
if ((input[i] / n) != 0 )
System.out.println(
"Element " + (i + 1 ) + " occurs "
+ input[i] / n + " times" );
input[i] = input[i] % n + 1 ;
}
}
public static void main(String[] args)
{
int [] arr
= { 1 , 1 , 1 , 2 , 3 , 3 , 5 , 5 , 8 , 8 , 8 , 9 , 9 , 10 };
int n = arr.length;
findFrequency(arr, n);
}
}
|
Python3
def findFrequency( input , n):
for i in range (n):
input [i] - = 1
for i in range (n):
input [ input [i] % n] + = n
for i in range (n):
if input [i] / / n:
print ( "Element" , i + 1 , "occurs" , input [i] / / n, "times" )
input [i] = input [i] % n + 1
if __name__ = = "__main__" :
arr = [ 1 , 1 , 1 , 2 , 3 , 3 , 5 , 5 , 8 , 8 , 8 , 9 , 9 , 10 ]
n = len (arr)
findFrequency(arr, n)
|
C#
using System;
public class GFG {
static void findFrequency( int [] input, int n)
{
for ( int i = 0; i < n; i++)
input[i]--;
for ( int i = 0; i < n; i++)
input[input[i] % n] += n;
for ( int i = 0; i < n; i++) {
if ((input[i] / n) != 0)
Console.WriteLine(
"Element " + (i + 1) + " occurs "
+ input[i] / n + " times" );
input[i] = input[i] % n + 1;
}
}
public static void Main(String[] args)
{
int [] arr
= { 1, 1, 1, 2, 3, 3, 5, 5, 8, 8, 8, 9, 9, 10 };
int n = arr.Length;
findFrequency(arr, n);
}
}
|
Javascript
<script>
function findFrequency(input, n)
{
for (let i = 0; i < n; i++)
input[i]--;
for (let i = 0; i < n; i++)
input[input[i] % n] += n;
console.log(input)
for (let i = 0; i < n; i++) {
if (Math.floor(input[i] / n))
document.write( "Element " + (i + 1) +
" occurs " + Math.floor(input[i] / n) + " times <br>" );
input[i] = input[i] % n + 1;
}
}
let arr = [1, 1, 1, 2, 3, 3, 5, 5, 8, 8, 8, 9, 9, 10];
let n = arr.length;
findFrequency(arr, n);
</script>
|
Output
Element 1 occurs 3 times
Element 2 occurs 1 times
Element 3 occurs 2 times
Element 5 occurs 2 times
Element 8 occurs 3 times
Element 9 occurs 2 times
Element 10 occurs 1 times
Time Complexity: O(N)
Auxiliary Space: O(1)
Frequency of each element in a limited range array using Counting Sort algorithm:
C
#include <stdio.h>
int * frequencyCount( int arr[], int n, int p) {
int * freq = calloc (p, sizeof ( int ));
for ( int i = 0; i < n; i++) {
if (arr[i] >= 1 && arr[i] <= p) {
freq[arr[i]-1]++;
}
}
for ( int i = 0; i < p; i++) {
printf ( "%d occurring %d times.\n" , i+1, freq[i]);
}
return freq;
}
int main() {
int arr[] = {2, 2, 6, 6, 7, 7, 7, 11};
int n = 8;
int p = 11;
int * freq = frequencyCount(arr, n, p);
for ( int i = 0; i < p; i++) {
printf ( "%d " ,freq[i] );
}
free (freq);
return 0;
}
|
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > frequencyCount( int arr[], int n, int p)
{
vector< int > freq(p, 0);
for ( int i = 0; i < n; i++) {
if (arr[i] >= 1 && arr[i] <= p) {
freq[arr[i] - 1]++;
}
}
for ( int i = 0; i < p; i++) {
cout << i + 1 << " occurring " << freq[i]
<< " times." << endl;
}
return freq;
}
int main()
{
int arr[] = { 2, 2, 6, 6, 7, 7, 7, 11 };
int n = 8;
int p = 11;
vector< int > freq = frequencyCount(arr, n, p);
for ( int i = 0; i < freq.size(); i++) {
cout << freq[i] << " " ;
}
cout << endl;
return 0;
}
|
Python3
def frequencyCount(arr, n, p):
freq = [ 0 ] * p
for i in range (n):
if arr[i] > = 1 and arr[i] < = p:
freq[arr[i] - 1 ] + = 1
for i in range (p):
print (i + 1 , "occurring" , freq[i], "times." )
return freq
if __name__ = = '__main__' :
arr = [ 2 , 2 , 6 , 6 , 7 , 7 , 7 , 11 ]
n = len (arr)
p = 11
freq = frequencyCount(arr, n, p)
print (freq)
|
Java
import java.util.Arrays;
public class Solution {
public int [] frequencyCount( int [] arr, int n, int p) {
int [] freq = new int [p];
for ( int i = 0 ; i < n; i++) {
if (arr[i] >= 1 && arr[i] <= p) {
freq[arr[i]- 1 ]++;
}
}
for ( int i = 0 ; i < p; i++) {
System.out.println((i+ 1 ) + " occurring " + freq[i] + " times." );
}
return freq;
}
public static void main(String[] args) {
int [] arr = { 2 , 2 , 6 , 6 , 7 , 7 , 7 , 11 };
int n = 8 ;
int p = 11 ;
Solution solution = new Solution();
int [] freq = solution.frequencyCount(arr, n, p);
System.out.println(Arrays.toString(freq));
}
}
|
Javascript
function frequencyCount(arr, n, p) {
let freq = new Array(p).fill(0);
for (let i = 0; i < n; i++) {
if (arr[i] >= 1 && arr[i] <= p) {
freq[arr[i] - 1]++;
}
}
for (let i = 0; i < p; i++) {
console.log(i + 1 + " occurring " + freq[i] + " times." );
}
return freq;
}
function main() {
let arr = [2, 2, 6, 6, 7, 7, 7, 11];
let n = 8;
let p = 11;
let freq = frequencyCount(arr, n, p);
console.log(freq.join( " " ));
}
main();
|
C#
using System;
class Program {
static int [] FrequencyCount( int [] arr, int n, int p) {
int [] freq = new int [p];
for ( int i = 0; i < n; i++) {
if (arr[i] >= 1 && arr[i] <= p) {
freq[arr[i]-1]++;
}
}
for ( int i = 0; i < p; i++) {
Console.WriteLine( "{0} occurring {1} times." , i+1, freq[i]);
}
return freq;
}
static void Main() {
int [] arr = {2, 2, 6, 6, 7, 7, 7, 11};
int n = 8;
int p = 11;
int [] freq = FrequencyCount(arr, n, p);
for ( int i = 0; i < p; i++) {
Console.Write(freq[i] + " " );
}
}
}
|
Output
1 occurring 0 times.
2 occurring 2 times.
3 occurring 0 times.
4 occurring 0 times.
5 occurring 0 times.
6 occurring 2 times.
7 occurring 3 times.
8 occurring 0 times.
9 occurring 0 times.
10 occurring 0 times.
11 occurring 1 times.
The time complexity of the frequencyCount function is O(n), where n is the length of the input array arr. This is because the function iterates over the entire array once to calculate the frequency of each element.
The Auxiliary space of the frequencyCount function is O(p), where p is the range of the elements in the input array. This is because the function creates a new list freq of size p to store the frequency of each element in the range 1 to p.
Share your thoughts in the comments
Please Login to comment...