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); |
2
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> |
2
Time Complexity: O(log(N))
Auxiliary Space: O(N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!