Given an array of n non-negative integers. The task is to find frequency of a particular element in the arbitrary range of array[]. The range is given as positions (not 0 based indexes) in array. There can be multiple queries of given type.
Examples:
Input : arr[] = {2, 8, 6, 9, 8, 6, 8, 2, 11};
left = 2, right = 8, element = 8
left = 2, right = 5, element = 6
Output : 3
1
The element 8 appears 3 times in arr[left-1..right-1]
The element 6 appears 1 time in arr[left-1..right-1]
Naive approach: is to traverse from left to right and update count variable whenever we find the element.
Below is the code of Naive approach:-
C++
#include<bits/stdc++.h>
using namespace std;
int findFrequency( int arr[], int n, int left,
int right, int element)
{
int count = 0;
for ( int i=left-1; i<=right; ++i)
if (arr[i] == element)
++count;
return count;
}
int main()
{
int arr[] = {2, 8, 6, 9, 8, 6, 8, 2, 11};
int n = sizeof (arr) / sizeof (arr[0]);
cout << "Frequency of 2 from 1 to 6 = "
<< findFrequency(arr, n, 1, 6, 2) << endl;
cout << "Frequency of 8 from 4 to 9 = "
<< findFrequency(arr, n, 4, 9, 8);
return 0;
}
|
Java
class GFG {
public static int findFrequency( int arr[], int n,
int left, int right,
int element)
{
int count = 0 ;
for ( int i = left - 1 ; i < right; ++i)
if (arr[i] == element)
++count;
return count;
}
public static void main(String[] args)
{
int arr[] = { 2 , 8 , 6 , 9 , 8 , 6 , 8 , 2 , 11 };
int n = arr.length;
System.out.println( "Frequency of 2 from 1 to 6 = " +
findFrequency(arr, n, 1 , 6 , 2 ));
System.out.println( "Frequency of 8 from 4 to 9 = " +
findFrequency(arr, n, 4 , 9 , 8 ));
}
}
|
Python3
def findFrequency(arr, n, left, right, element):
count = 0
for i in range (left - 1 , right):
if (arr[i] = = element):
count + = 1
return count
arr = [ 2 , 8 , 6 , 9 , 8 , 6 , 8 , 2 , 11 ]
n = len (arr)
print ( "Frequency of 2 from 1 to 6 = " ,
findFrequency(arr, n, 1 , 6 , 2 ))
print ( "Frequency of 8 from 4 to 9 = " ,
findFrequency(arr, n, 4 , 9 , 8 ))
|
C#
using System;
class GFG {
public static int findFrequency( int []arr, int n,
int left, int right,
int element)
{
int count = 0;
for ( int i = left - 1; i < right; ++i)
if (arr[i] == element)
++count;
return count;
}
public static void Main()
{
int []arr = {2, 8, 6, 9, 8, 6, 8, 2, 11};
int n = arr.Length;
Console.WriteLine( "Frequency of 2 from 1 to 6 = " +
findFrequency(arr, n, 1, 6, 2));
Console.Write( "Frequency of 8 from 4 to 9 = " +
findFrequency(arr, n, 4, 9, 8));
}
}
|
PHP
<?php
function findFrequency(& $arr , $n , $left ,
$right , $element )
{
$count = 0;
for ( $i = $left - 1; $i <= $right ; ++ $i )
if ( $arr [ $i ] == $element )
++ $count ;
return $count ;
}
$arr = array (2, 8, 6, 9, 8, 6, 8, 2, 11);
$n = sizeof( $arr );
echo "Frequency of 2 from 1 to 6 = " .
findFrequency( $arr , $n , 1, 6, 2) . "\n" ;
echo "Frequency of 8 from 4 to 9 = " .
findFrequency( $arr , $n , 4, 9, 8);
?>
|
Javascript
<script>
function findFrequency(arr,n,left,right,element)
{
let count = 0;
for (let i = left - 1; i < right; ++i)
if (arr[i] == element)
++count;
return count;
}
let arr=[2, 8, 6, 9, 8, 6, 8, 2, 11];
let n = arr.length;
document.write( "Frequency of 2 from 1 to 6 = " +
findFrequency(arr, n, 1, 6, 2)+ "<br>" );
document.write( "Frequency of 8 from 4 to 9 = " +
findFrequency(arr, n, 4, 9, 8));
</script>
|
Output:
Frequency of 2 from 1 to 6 = 1
Frequency of 8 from 4 to 9 = 2
Time complexity of this approach is O(right – left + 1) or O(n)
Auxiliary space: O(1)
An Efficient approach is to use hashing. In C++, we can use unordered_map
- At first, we will store the position in map[] of every distinct element as a vector like that
int arr[] = {2, 8, 6, 9, 8, 6, 8, 2, 11};
map[2] = {1, 8}
map[8] = {2, 5, 7}
map[6] = {3, 6}
ans so on...
- As we can see that elements in map[] are already in sorted order (Because we inserted elements from left to right), the answer boils down to find the total count in that hash map[] using binary search like method.
- In C++ we can use lower_bound which will returns an iterator pointing to the first element in the range [first, last] which has a value not less than ‘left’. and upper_bound returns an iterator pointing to the first element in the range [first,last) which has a value greater than ‘right’.
- After that we just need to subtract the upper_bound() and lower_bound() result to get the final answer. For example, suppose if we want to find the total count of 8 in the range from [1 to 6], then the map[8] of lower_bound() function will return the result 0 (pointing to 2) and upper_bound() will return 2 (pointing to 7), so we need to subtract the both the result like 2 – 0 = 2 .
Below is the code of above approach
C++
#include<bits/stdc++.h>
using namespace std;
unordered_map< int , vector< int > > store;
int findFrequency( int arr[], int n, int left,
int right, int element)
{
int a = lower_bound(store[element].begin(),
store[element].end(),
left)
- store[element].begin();
int b = upper_bound(store[element].begin(),
store[element].end(),
right)
- store[element].begin();
return b-a;
}
int main()
{
int arr[] = {2, 8, 6, 9, 8, 6, 8, 2, 11};
int n = sizeof (arr) / sizeof (arr[0]);
for ( int i=0; i<n; ++i)
store[arr[i]].push_back(i+1);
cout << "Frequency of 2 from 1 to 6 = "
<< findFrequency(arr, n, 1, 6, 2) <<endl;
cout << "Frequency of 8 from 4 to 9 = "
<< findFrequency(arr, n, 4, 9, 8);
return 0;
}
|
Python3
from collections import defaultdict as dict
from bisect import bisect_left as lower_bound
from bisect import bisect_right as upper_bound
store = dict ( list )
def findFrequency(arr, n, left, right, element):
a = lower_bound(store[element], left)
b = upper_bound(store[element], right)
return b - a
arr = [ 2 , 8 , 6 , 9 , 8 , 6 , 8 , 2 , 11 ]
n = len (arr)
for i in range (n):
store[arr[i]].append(i + 1 )
print ( "Frequency of 2 from 1 to 6 = " ,
findFrequency(arr, n, 1 , 6 , 2 ))
print ( "Frequency of 8 from 4 to 9 = " ,
findFrequency(arr, n, 4 , 9 , 8 ))
|
Output:
Frequency of 2 from 1 to 6 = 1
Frequency of 8 from 4 to 9 = 2
This approach will be beneficial if we have a large number of queries of an arbitrary range asking the total frequency of particular element.
Time complexity: O(log N) for single query.
This article is contributed by Shubham Bansal. 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.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.