Find frequency of each element in a limited range array in less than O(n) time

Given a sorted array of positive integers, the 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

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

Method 1: This method uses the technique of Linear Search to solve the following. 

  • Approach: 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.
  • Algorithm: 
    1. Create a HashMap to map the frequency to element, i.e to store element-frequency pair.
    2. Traverse the array from start to end.
    3. For each element in the array update the frequency, i.e hm[array[i]]++
    4. Traverse the HashMap and print the element frequency pair.
  • Implementation:
     

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to count number of occurrences of
// each element in the array #include <iostream>
#include <bits/stdc++.h>
using namespace std;
 
// It prints number of
// occurrences of each element in the array.
void findFrequency(int arr[], int n)
{
    // HashMap to store frequencies
    unordered_map<int, int> mp;
 
    // traverse the array
    for (int i = 0; i < n; i++) {
        // update the frequency
        mp[arr[i]]++;
    }
 
    // traverse the hashmap
    for (auto i : mp) {
        cout << "Element " << i.first << " occurs "
             << i.second << " 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;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python program to count number of occurrences of
# each element in the array #include <iostream>
 
# It prints number of
# occurrences of each element in the array.
def findFrequency(arr, n):
     
    # HashMap to store frequencies
    mp = {}
 
    # traverse the array
    for i in range(n):
 
        # update the frequency
        if arr[i] not in mp:
            mp[arr[i]] = 0
        mp[arr[i]] += 1
         
    # traverse the hashmap
    for i in mp:
        print("Element", i, "occurs", mp[i], "times")
     
# Driver function
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 shubhamsingh10

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to count number
// of occurrences of each
// element in the array
using System;
using System.Collections.Generic;
class GFG{
 
// It prints number of
// occurrences of each
// element in the array.
static void findFrequency(int [] arr,
                          int n)
{
  // HashMap to store frequencies
  Dictionary <int,
              int > mp =
              new Dictionary<int,
                             int>();
 
  // traverse the array
  for (int i = 0; i < n; i++)
  {
    // update the frequency
    if (!mp.ContainsKey(arr[i]))
      mp[arr[i]] = 0;
 
    mp[arr[i]]++;
  }
 
  // traverse the hashmap
  foreach(KeyValuePair<int,
                       int> kvp in mp)
    Console.WriteLine("Element " + kvp.Key +
                      " occurs " + kvp.Value +
                      " times");
}
 
// Driver function
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);
}
}
 
// This code is contributed by Chitranayal

chevron_right


  • 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
  • Complexity Analysis: 
    • Time Complexity:O(n), only one traversal of the array is needed.
    • Space Complexity:O(n), to store the elements in the HashMap O(n) extra space is needed.

Method 2: This method uses the technique of Binary Search to arrive at the solution.  

  • Approach: 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 ends of a subarray are 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. 
     
  • Algorithm: 
    1. Create a HashMap (hm) to store the frequency of elements.
    2. Create a recursive function that accepts an array and size.
    3. 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
    4. Else divide the array into two equal halves and call the function recursively for both the halves.
    5. Traverse the hashmap and print the element frequency pair.
  • Implementation: 
     

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


  • 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
  • Complexity Analysis: 
    • 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).
    • Space Complexity:O(n). 
      To store the elements in the HashMap O(n) extra space is needed.

https://youtu.be/B2hI-QPoisk 
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.
 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Recommended Posts: