Find frequency of each element in a limited range array in less than O(n) time
Given an sorted array of positive integers, count number of occurrences for each element in the array. Assume all elements in the array are less than some constant M.
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
Method 1 (Linear Search)
The idea is traverse the input array and for each distinct element of array, store its frequency in a map and finally print the map. This approach takes O(n) time.
Method 2 (Use Binary Search)
This problem can be solved in less than O(n) using a modified binary search. The idea is to recursively divide the array into two equal subarrays if its end elements are different. If both its end elements are same, that means that all elements in the subarray is also same as the array is already sorted. We then simply increment the count of the element by size of the subarray.
The time complexity of above approach is O(m log n), where m is number of distinct elements in the array of size n. Since m <= M (a constant), the time complexity of this solution is O(log n).
Below is the implementation of above idea –
C++
// C++ program to count number of occurrences of // each element in the array in less than O(n) time #include <iostream> #include <vector> using namespace std; // A recursive function to count number of occurrences // for each element in the array without traversing // the whole array void findFrequencyUtil(int arr[], int low, int high, vector<int>& freq) { // If element at index low is equal to element // at index high in the array if (arr[low] == arr[high]) { // increment the frequency of the element // by count of elements between high and low freq[arr[low]] += high - low + 1; } else { // Find mid and recurse for left and right // subarray int mid = (low + high) / 2; findFrequencyUtil(arr, low, mid, freq); findFrequencyUtil(arr, mid + 1, high, freq); } } // A wrapper over recursive function // findFrequencyUtil(). It print number of // occurrences of each element in the array. void findFrequency(int arr[], int n) { // create a empty vector to store frequencies // and initialize it by 0. Size of vector is // maximum value (which is last value in sorted // array) plus 1. vector<int> freq(arr[n - 1] + 1, 0); // Fill the vector with frequency findFrequencyUtil(arr, 0, n - 1, freq); // Print the frequencies for (int i = 0; i <= arr[n - 1]; i++) if (freq[i] != 0) cout << "Element " << i << " occurs " << freq[i] << " times" << endl; } // Driver function 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
// Java program to count number of occurrences of // each element in the array in less than O(n) time import java.util.*; class GFG { // A recursive function to count number of occurrences // for each element in the array without traversing // the whole array static void findFrequencyUtil(int arr[], int low, int high, int[] freq) { // If element at index low is equal to element // at index high in the array if (arr[low] == arr[high]) { // increment the frequency of the element // by count of elements between high and low freq[arr[low]] += high - low + 1; } else { // Find mid and recurse for left and right // subarray int mid = (low + high) / 2; findFrequencyUtil(arr, low, mid, freq); findFrequencyUtil(arr, mid + 1, high, freq); } } // A wrapper over recursive function // findFrequencyUtil(). It print number of // occurrences of each element in the array. static void findFrequency(int arr[], int n) { // create a empty vector to store frequencies // and initialize it by 0. Size of vector is // maximum value (which is last value in sorted // array) plus 1. int []freq = new int[arr[n - 1] + 1]; // Fill the vector with frequency findFrequencyUtil(arr, 0, n - 1, freq); // Print the frequencies for (int i = 0; i <= arr[n - 1]; i++) if (freq[i] != 0) System.out.println("Element " + i + " occurs " + freq[i] + " times"); } // Driver Code 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); } } // This code is contributed by 29AjayKumar |
Python3
# Python 3 program to count number of occurrences of # each element in the array in less than O(n) time # A recursive function to count number of occurrences # for each element in the array without traversing # the whole array def findFrequencyUtil(arr, low, high, freq): # If element at index low is equal to element # at index high in the array if (arr[low] == arr[high]): # increment the frequency of the element # by count of elements between high and low freq[arr[low]] += high - low + 1 else: # Find mid and recurse for left # and right subarray mid = int((low + high) / 2) findFrequencyUtil(arr, low, mid, freq) findFrequencyUtil(arr, mid + 1, high, freq) # A wrapper over recursive function # findFrequencyUtil(). It print number of # occurrences of each element in the array. def findFrequency(arr, n): # create a empty vector to store frequencies # and initialize it by 0. Size of vector is # maximum value (which is last value in sorted # array) plus 1. freq = [0 for i in range(n - 1 + 1)] # Fill the vector with frequency findFrequencyUtil(arr, 0, n - 1, freq) # Print the frequencies for i in range(0, arr[n - 1] + 1, 1): if (freq[i] != 0): print("Element", i, "occurs", freq[i], "times") # Driver Code if __name__ == '__main__': arr = [1, 1, 1, 2, 3, 3, 5, 5, 8, 8, 8, 9, 9, 10] n = len(arr) findFrequency(arr, n) # This code is contributed by # Surendra_Gangwar |
C#
// C# program to count number of occurrences of // each element in the array in less than O(n) time using System; class GFG { // A recursive function to count number of occurrences // for each element in the array without traversing // the whole array static void findFrequencyUtil(int []arr, int low, int high, int[] freq) { // If element at index low is equal to element // at index high in the array if (arr[low] == arr[high]) { // increment the frequency of the element // by count of elements between high and low freq[arr[low]] += high - low + 1; } else { // Find mid and recurse for left and right // subarray int mid = (low + high) / 2; findFrequencyUtil(arr, low, mid, freq); findFrequencyUtil(arr, mid + 1, high, freq); } } // A wrapper over recursive function // findFrequencyUtil(). It print number of // occurrences of each element in the array. static void findFrequency(int []arr, int n) { // create a empty vector to store frequencies // and initialize it by 0. Size of vector is // maximum value (which is last value in sorted // array) plus 1. int []freq = new int[arr[n - 1] + 1]; // Fill the vector with frequency findFrequencyUtil(arr, 0, n - 1, freq); // Print the frequencies for (int i = 0; i <= arr[n - 1]; i++) if (freq[i] != 0) Console.WriteLine("Element " + i + " occurs " + freq[i] + " times"); } // Driver Code 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); } } // This code is contributed by Princi Singh |
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
This article is contributed by Aditya Goel. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@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.
Recommended Posts:
- Find even occurring elements in an array of limited range
- Find duplicates in a given array when elements are not limited to a range
- Find the missing number in a sorted array of limited range
- Smallest element repeated exactly ‘k’ times (not limited to small range)
- Find the element having different frequency than other array elements
- Find element in a sorted array whose frequency is greater than or equal to n/2.
- Given an array and two integers l and r, find the kth largest element in the range [l, r]
- Replace each element by the difference of the total size of the array and frequency of that element
- Array range queries for elements with frequency same as value
- Remove elements from the array whose frequency lies in the range [l, r]
- Fill an array based on frequency where elements are in range from 0 to n-1
- Frequency of each element of an array of small ranged values
- Cumulative frequency of count of each element in an unsorted array
- Range Query on array whose each element is XOR of index value and previous element
- Constant time range add operation on an array



