Count distinct elements from a range of a sorted sequence from a given frequency array
Last Updated :
24 Aug, 2023
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: 2
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.
Code-
C++
// C++ program for the above approach
#include<bits/stdc++.h>
using namespace std;
// 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)
{
vector<int> vec;
for(int i=0;i<arr.size();i++){
int temp=arr[i];
for(int j=0;j<temp;j++){
vec.push_back(i+1);
}
}
int curr=INT_MIN;
int count=0;
for(int i=L-1;i<R;i++){
if(curr!=vec[i]){
count++;
curr=vec[i];
}
}
cout<<count<<endl;
}
// Driver Code
int main()
{
vector<int> arr{ 3, 6, 7, 1, 8 };
int L = 3;
int R = 7;
countDistinct(arr, L, R);
}
Java
import java.util.*;
class GFG {
// Function to count the number of
// distinct elements over the range
// [L, R] in the sorted sequence
static void countDistinct(ArrayList<Integer> arr, int L,
int R)
{
ArrayList<Integer> vec = new ArrayList<Integer>();
for (int i = 0; i < arr.size(); i++) {
int temp = arr.get(i);
for (int j = 0; j < temp; j++) {
vec.add(i + 1);
}
}
int curr = Integer.MIN_VALUE;
int count = 0;
for (int i = L - 1; i < R; i++) {
if (curr != vec.get(i)) {
count++;
curr = vec.get(i);
}
}
System.out.println(count);
}
// Driver Code
public static void main(String[] args)
{
ArrayList<Integer> arr = new ArrayList<Integer>(
Arrays.asList(3, 6, 7, 1, 8));
int L = 3;
int R = 7;
countDistinct(arr, L, R);
}
}
Python3
# Python program for the above approach
def countDistinct(arr, L, R):
# create a new vector
vec = []
for i in range(len(arr)):
temp = arr[i]
for j in range(temp):
vec.append(i+1)
curr = float('-inf')
count = 0
for i in range(L-1, R):
if curr != vec[i]:
count += 1
curr = vec[i]
print(count)
# Driver Code
if __name__ == '__main__':
arr = [3, 6, 7, 1, 8]
L = 3
R = 7
countDistinct(arr, L, R)
C#
using System;
using System.Collections.Generic;
class GFG
{
// 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)
{
List<int> vec = new List<int>();
// Create a sorted sequence with occurrences of elements from the input array
foreach (int temp in arr)
{
for (int j = 0; j < temp; j++)
{
vec.Add(arr.IndexOf(temp) + 1);
}
}
int curr = int.MinValue;
int count = 0;
// Count the number of distinct elements in the range [L, R]
for (int i = L - 1; i < R; i++)
{
if (curr != vec[i])
{
count++;
curr = vec[i];
}
}
Console.WriteLine(count);
}
// Driver Code
static void Main()
{
List<int> arr = new List<int> { 3, 6, 7, 1, 8 };
int L = 3;
int R = 7;
CountDistinct(arr, L, R);
}
}
JavaScript
// Function to count the number of
// distinct elements over the range
// [L, R] in the sorted sequence
function countDistinct(arr, L, R) {
// creating sorted sequence
let vec = [];
for (let i = 0; i < arr.length; i++) {
let temp = arr[i];
for (let j = 0; j < temp; j++) {
vec.push(i + 1);
}
}
// Counting distinct elements
let curr = Number.MIN_SAFE_INTEGER;
let count = 0;
for (let i = L - 1; i < R; i++) {
if (curr !== vec[i]) {
count++;
curr = vec[i];
}
}
console.log(count);
}
// test case
let arr = [3, 6, 7, 1, 8];
let L = 3;
let R = 7;
countDistinct(arr, L, R);
Time Complexity: O(S + 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<bits/stdc++.h>
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
<script>
// Javascript program for the above approach
// Function to find the first index
// with value is at least element
function binarysearch(array, right, element)
{
// Update the value of left
let left = 1;
// Update the value of right
// Binary search for the element
while (left <= right)
{
// Find the middle element
let mid = Math.floor((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
function countDistinct(arr, L, R)
{
// Stores the count of distinct
// elements
let count = 0;
// Create the prefix sum array
let pref = Array.from(
{length: arr.length + 1}, (_, i) => 0);
for(let 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
let left = binarysearch(pref, arr.length + 1, L);
let right = binarysearch(pref, arr.length + 1, R);
// Print the resultant count
document.write((right - left) + 1);
}
// Driver Code
let arr = [ 3, 6, 7, 1, 8 ];
let L = 3;
let R = 7;
countDistinct(arr, L, R);
// This code is contributed by susmitakundugoaldanga
</script>
Time Complexity: O(log(N))
Auxiliary Space: O(N)
Similar Reads
Count all distinct pairs of repeating elements from the array for every array element
Given an array arr[] of N integers. For each element in the array, the task is to count the possible pairs (i, j), excluding the current element, such that i < j and arr[i] = arr[j]. Examples: Input: arr[] = {1, 1, 2, 1, 2}Output: 2 2 3 2 3Explanation:For index 1, remaining elements after excludi
7 min read
Cumulative frequency of count of each element in an unsorted array
Given an unsorted array. The task is to calculate the cumulative frequency of each element of the array using a count array.Examples: Input : arr[] = [1, 2, 2, 1, 3, 4]Output :1->2 2->4 3->5 4->6Input : arr[] = [1, 1, 1, 2, 2, 2]Output :1->3 2->6 A simple solution is to use two nes
9 min read
Fill an array based on frequency where elements are in range from 0 to n-1
Given an array of positive integers with duplicate allowed. The array contains elements from range 0 to n-1. The task is to fill the array such that arr[i] contains the frequency of i. Examples : Input : arr[] = {1, 4, 3, 4, 1, 1, 4, 4, 4, 7} Output : arr[] = {0, 3, 0, 1, 5, 0, 0, 1, 0, 0} Here 0 ap
5 min read
Count subarrays having a single distinct element that can be obtained from a given array
Given an array arr[] of size N, the task is to count the number of subarrays consisting of a single distinct element that can be obtained from a given array. Examples: Input: N = 4, arr[] = { 2, 2, 2, 2 }Output: 7Explanation: All such subarrays {{2}, {2}, {2}, {2}, {2, 2}, {2, 2, 2}, {2, 2, 2, 2}}.
5 min read
Count of smaller or equal elements in sorted array
Given a sorted array of size n. Find a number of elements that are less than or equal to a given element. Examples: Input : arr[] = {1, 2, 4, 5, 8, 10} key = 9 Output : 5 Elements less than or equal to 9 are 1, 2, 4, 5, 8 therefore result will be 5. Input : arr[] = {1, 2, 2, 2, 5, 7, 9} key = 2 Outp
15+ min read
Sorting element of an array by frequency in decreasing order
Given an array arr[] of N integers. The task is to sort the array arr[] according to the frequency of elements in decreasing order. Note: If the frequencies of the two elements are the same, then the smaller element should come first. Examples: Input: arr[] = { 4, 4, 5, 6, 4, 2, 2, 8, 5 } Output: 4
15+ min read
Count of subarrays which forms a permutation from given Array elements
Given an array A[] consisting of integers [1, N], the task is to count the total number of subarrays of all possible lengths x (1 ? x ? N), consisting of a permutation of integers [1, x] from the given array. Examples: Input: A[] = {3, 1, 2, 5, 4} Output: 4 Explanation: Subarrays forming a permutati
6 min read
Queries to count array elements from a given range having a single set bit
Given an array arr[] consisting of positive integers and an array Q[][] consisting of queries, the task for every ith query is to count array elements from the range [Q[i][0], Q[i][1]] with only one set bit. Examples: Input: arr[] = {12, 11, 16, 8, 2, 5, 1, 3, 256, 1}, queries[][] = {{0, 9}, {4, 9}}
7 min read
Queries to count array elements from a given range having a single set bit
Given an array arr[] consisting of N integers and a 2D array Q[][] consisting of queries of the following two types: 1 L R: Print the count of numbers from the range [L, R] having only a single set bit.2 X V: Update the array element at Xth index with V.Examples: Input: arr[] = { 12, 11, 16, 2, 32 }
15+ min read
Count Distinct ( Unique ) elements in an array
Given an array arr[] of length N, The task is to count all distinct elements in arr[]. Examples: Input: arr[] = {10, 20, 20, 10, 30, 10}Output: 3Explanation: There are three distinct elements 10, 20, and 30. Input: arr[] = {10, 20, 20, 10, 20}Output: 2 Naïve Approach: Create a count variable and ru
15 min read