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

• Difficulty Level : Expert
• Last Updated : 28 Jul, 2022

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:

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(log(N))
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up