# Count distinct elements from a range of a sorted sequence from a given frequency array

• Difficulty Level : Expert
• Last Updated : 12 Jun, 2021

Given two integers L and R and an array arr[] consisting of N positive integers( 1-based indexing ) such that the frequency of ith element of a sorted sequence, say A[], is arr[i]. The task is to find the number of distinct elements from the range [L, R] in the sequence A[].

Examples:

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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input: arr[] = {3, 6, 7, 1, 8}, L = 3, R = 7
Output: 2
Explanation: From the given frequency array, the sorted array will be {1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, ….}. Now, the number of distinct elements from the range [3, 7] is 2( = {1, 2}).

Input: arr[] = {1, 2, 3, 4}, L = 3, R = 4
Output: 1

Naive Approach: The simplest approach to solve the given problem is to construct the sorted sequence from the given array arr[] using the given frequencies and then traverse the constructed array over the range [L, R] to count the number of distinct elements.

Time Complexity: O(N + R – L)
Auxiliary Space: O(S), where S is the sum of the array elements.

Efficient Approach: The above approach can be optimized by using the Binary Search and the prefix sum technique to find the number of distinct elements over the range [L, R]. Follow the steps below to solve the given problem:

• Initialize an auxiliary array, say prefix[] that stores the prefix sum of the given array elements.
• Find the prefix sum of the given array and stored it in the array prefix[].
• By using binary search, find the first index at which the value in prefix[] is at least L, say left.
• By using binary search, find the first index at which the value in prefix[] is at least R, say right.
• After completing the above steps, print the value of (right – left + 1) as the result.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include``using` `namespace` `std;` `// Function to find the first index``// with value is at least element``int` `binarysearch(``int` `array[], ``int` `right,``                 ``int` `element)``{``    ` `    ``// Update the value of left``    ``int` `left = 1;` `    ``// Update the value of right``     ` `    ``// Binary search for the element``    ``while` `(left <= right)``    ``{``        ` `        ``// Find the middle element``        ``int` `mid = (left + right / 2);` `        ``if` `(array[mid] == element)``        ``{``            ``return` `mid;``        ``}` `        ``// Check if the value lies``        ``// between the elements at``        ``// index mid - 1 and mid``        ``if` `(mid - 1 > 0 && array[mid] > element &&``           ``array[mid - 1] < element)``        ``{``            ``return` `mid;``        ``}` `        ``// Check in the right subarray``        ``else` `if` `(array[mid] < element)``        ``{``            ` `            ``// Update the value``            ``// of left``            ``left = mid + 1;``        ``}` `        ``// Check in left subarray``        ``else``        ``{``            ` `            ``// Update the value of``            ``// right``            ``right = mid - 1;``        ``}``    ``}``    ``return` `1;``}` `// Function to count the number of``// distinct elements over the range``// [L, R] in the sorted sequence``void` `countDistinct(vector<``int``> arr,``                          ``int` `L, ``int` `R)``{``    ` `    ``// Stores the count of distinct``    ``// elements``    ``int` `count = 0;` `    ``// Create the prefix sum array``    ``int` `pref[arr.size() + 1];` `    ``for``(``int` `i = 1; i <= arr.size(); ++i)``    ``{``        ` `        ``// Update the value of count``        ``count += arr[i - 1];` `        ``// Update the value of pref[i]``        ``pref[i] = count;``    ``}` `    ``// Calculating the first index``    ``// of L and R using binary search``    ``int` `left = binarysearch(pref, arr.size() + 1, L);``    ``int` `right = binarysearch(pref, arr.size() + 1, R);` `    ``// Print the resultant count``    ``cout << right - left + 1;``}` `// Driver Code``int` `main()``{``    ``vector<``int``> arr{ 3, 6, 7, 1, 8 };``    ``int` `L = 3;``    ``int` `R = 7;``    ` `    ``countDistinct(arr, L, R);``}` `// This code is contributed by ipg2016107`

## Java

 `// Java program for the above approach``import` `java.io.*;``import` `java.util.*;` `class` `GFG {` `    ``// Function to find the first index``    ``// with value is at least element``    ``static` `int` `binarysearch(``int` `array[],``                            ``int` `element)``    ``{``        ``// Update the value of left``        ``int` `left = ``1``;` `        ``// Update the value of right``        ``int` `right = array.length - ``1``;` `        ``// Binary search for the element``        ``while` `(left <= right) {` `            ``// Find the middle element``            ``int` `mid = (``int``)(left + right / ``2``);` `            ``if` `(array[mid] == element) {``                ``return` `mid;``            ``}` `            ``// Check if the value lies``            ``// between the elements at``            ``// index mid - 1 and mid``            ``if` `(mid - ``1` `> ``0``                ``&& array[mid] > element``                ``&& array[mid - ``1``] < element) {` `                ``return` `mid;``            ``}` `            ``// Check in the right subarray``            ``else` `if` `(array[mid] < element) {` `                ``// Update the value``                ``// of left``                ``left = mid + ``1``;``            ``}` `            ``// Check in left subarray``            ``else` `{` `                ``// Update the value of``                ``// right``                ``right = mid - ``1``;``            ``}``        ``}` `        ``return` `1``;``    ``}` `    ``// Function to count the number of``    ``// distinct elements over the range``    ``// [L, R] in the sorted sequence``    ``static` `void` `countDistinct(``int` `arr[],``                              ``int` `L, ``int` `R)``    ``{``        ``// Stores the count of distinct``        ``// elements``        ``int` `count = ``0``;` `        ``// Create the prefix sum array``        ``int` `pref[] = ``new` `int``[arr.length + ``1``];` `        ``for` `(``int` `i = ``1``; i <= arr.length; ++i) {` `            ``// Update the value of count``            ``count += arr[i - ``1``];` `            ``// Update the value of pref[i]``            ``pref[i] = count;``        ``}` `        ``// Calculating the first index``        ``// of L and R using binary search``        ``int` `left = binarysearch(pref, L);``        ``int` `right = binarysearch(pref, R);` `        ``// Print the resultant count``        ``System.out.println(``            ``(right - left) + ``1``);``    ``}` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int` `arr[] = { ``3``, ``6``, ``7``, ``1``, ``8` `};``        ``int` `L = ``3``;``        ``int` `R = ``7``;``        ``countDistinct(arr, L, R);``    ``}``}`

## Python3

 `# Python3 program for the above approach` `# Function to find the first index``# with value is at least element``def` `binarysearch(array,  right,``                 ``element):` `    ``# Update the value of left``    ``left ``=` `1` `    ``# Update the value of right` `    ``# Binary search for the element``    ``while` `(left <``=` `right):` `        ``# Find the middle element``        ``mid ``=` `(left ``+` `right ``/``/` `2``)` `        ``if` `(array[mid] ``=``=` `element):``            ``return` `mid` `        ``# Check if the value lies``        ``# between the elements at``        ``# index mid - 1 and mid``        ``if` `(mid ``-` `1` `> ``0` `and` `array[mid] > element ``and``                        ``array[mid ``-` `1``] < element):``            ``return` `mid` `        ``# Check in the right subarray``        ``elif` `(array[mid] < element):` `            ``# Update the value``            ``# of left``            ``left ``=` `mid ``+` `1` `        ``# Check in left subarray``        ``else``:` `            ``# Update the value of``            ``# right``            ``right ``=` `mid ``-` `1` `    ``return` `1` `# Function to count the number of``# distinct elements over the range``# [L, R] in the sorted sequence``def` `countDistinct(arr, L, R):` `    ``# Stores the count of distinct``    ``# elements``    ``count ``=` `0` `    ``# Create the prefix sum array``    ``pref ``=` `[``0``] ``*` `(``len``(arr) ``+` `1``)` `    ``for` `i ``in` `range``(``1``, ``len``(arr) ``+` `1``):` `        ``# Update the value of count``        ``count ``+``=` `arr[i ``-` `1``]` `        ``# Update the value of pref[i]``        ``pref[i] ``=` `count` `    ``# Calculating the first index``    ``# of L and R using binary search``    ``left ``=` `binarysearch(pref, ``len``(arr) ``+` `1``, L)``    ``right ``=` `binarysearch(pref, ``len``(arr) ``+` `1``, R)` `    ``# Print the resultant count``    ``print``(right ``-` `left ``+` `1``)` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:` `    ``arr ``=` `[ ``3``, ``6``, ``7``, ``1``, ``8` `]``    ``L ``=` `3``    ``R ``=` `7` `    ``countDistinct(arr, L, R)` `# This code is contributed by ukasp`

## C#

 `// C# program for the above approach``using` `System;``using` `System.Collections.Generic;` `class` `GFG{` `// Function to find the first index``// with value is at least element``static` `int` `binarysearch(``int` `[]array, ``int` `right,``                        ``int` `element)``{``    ` `    ``// Update the value of left``    ``int` `left = 1;` `    ``// Update the value of right``     ` `    ``// Binary search for the element``    ``while` `(left <= right)``    ``{``        ` `        ``// Find the middle element``        ``int` `mid = (left + right / 2);` `        ``if` `(array[mid] == element)``        ``{``            ``return` `mid;``        ``}` `        ``// Check if the value lies``        ``// between the elements at``        ``// index mid - 1 and mid``        ``if` `(mid - 1 > 0 && array[mid] > element &&``            ``array[mid - 1] < element)``        ``{``            ``return` `mid;``        ``}` `        ``// Check in the right subarray``        ``else` `if` `(array[mid] < element)``        ``{``            ` `            ``// Update the value``            ``// of left``            ``left = mid + 1;``        ``}` `        ``// Check in left subarray``        ``else``        ``{``            ` `            ``// Update the value of``            ``// right``            ``right = mid - 1;``        ``}``    ``}``    ``return` `1;``}` `// Function to count the number of``// distinct elements over the range``// [L, R] in the sorted sequence``static` `void` `countDistinct(List<``int``> arr,``                          ``int` `L, ``int` `R)``{``    ` `    ``// Stores the count of distinct``    ``// elements``    ``int` `count = 0;` `    ``// Create the prefix sum array``    ``int` `[]pref = ``new` `int``[arr.Count + 1];` `    ``for``(``int` `i = 1; i <= arr.Count; ++i)``    ``{``        ` `        ``// Update the value of count``        ``count += arr[i - 1];` `        ``// Update the value of pref[i]``        ``pref[i] = count;``    ``}` `    ``// Calculating the first index``    ``// of L and R using binary search``    ``int` `left = binarysearch(pref, arr.Count + 1, L);``    ``int` `right = binarysearch(pref, arr.Count + 1, R);` `    ``// Print the resultant count``    ``Console.Write(right - left + 1);``}` `// Driver Code``public` `static` `void` `Main()``{``    ``List<``int``> arr = ``new` `List<``int``>(){ 3, 6, 7, 1, 8 };``    ``int` `L = 3;``    ``int` `R = 7;``    ` `    ``countDistinct(arr, L, R);``}``}` `// This code is contributed by SURENDRA_GANGWAR`

## Javascript

 ``
Output:
`2`

Time Complexity: O(N)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up