Given an array of n integers. Count the total number of sub-arrays having total distinct elements, the same as that of the total distinct elements of the original array.
Examples:
Input : arr[] = {2, 1, 3, 2, 3}
Output : 5
Total distinct elements in array is 3
Total sub-arrays that satisfy the condition
are: Subarray from index 0 to 2
Subarray from index 0 to 3
Subarray from index 0 to 4
Subarray from index 1 to 3
Subarray from index 1 to 4
Input : arr[] = {2, 4, 5, 2, 1}
Output : 2
Input : arr[] = {2, 4, 4, 2, 4}
Output : 9
A Naive approach is to run a loop one inside another and consider all sub-arrays and, for every sub-array, count all distinct elements by using hashing and compare them with the total distinct elements of the original array.
- Initialise an unordered set unst1 to count distinct elements.
- Initialise a variable totalDist for total number of distinct elements in given array.
- Generate all the subarray and for every element count the distinct element in that subarray.
- Check if the number of distinct elements of the current subarray is equal to totalDist then increment the count by 1.
- Finally, return count.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int countDistictSubarray( int arr[], int n)
{
unordered_set< int > unst1;
for ( int i = 0; i < n; i++)
unst1.insert(arr[i]);
int totalDist = unst1.size();
int count = 0;
for ( int i = 0; i < n; i++) {
unordered_set< int > unst;
for ( int j = i; j < n; j++) {
unst.insert(arr[j]);
if (unst.size() == totalDist)
count++;
}
}
return count;
}
int main()
{
int arr[] = { 2, 1, 3, 2, 3 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << countDistictSubarray(arr, n) << endl;
return 0;
}
|
Java
import java.util.*;
public class Gfg {
public static int countDistictSubarray( int [] arr, int n)
{
Set<Integer> unst1 = new HashSet<>();
for ( int i = 0 ; i < n; i++)
unst1.add(arr[i]);
int totalDist = unst1.size();
int count = 0 ;
for ( int i = 0 ; i < n; i++) {
Set<Integer> unst = new HashSet<>();
for ( int j = i; j < n; j++) {
unst.add(arr[j]);
if (unst.size() == totalDist)
count++;
}
}
return count;
}
public static void main(String[] args)
{
int [] arr = { 2 , 1 , 3 , 2 , 3 };
int n = arr.length;
System.out.println(countDistictSubarray(arr, n));
}
}
|
Python3
def countDistictSubarray(arr, n):
unst1 = set (arr)
totalDist = len (unst1)
count = 0
for i in range (n):
unst = set ()
for j in range (i, n):
unst.add(arr[j])
if len (unst) = = totalDist:
count + = 1
return count
arr = [ 2 , 1 , 3 , 2 , 3 ]
n = len (arr)
print (countDistictSubarray(arr, n))
|
C#
using System;
using System.Collections.Generic;
class Gfg {
public static int countDistictSubarray( int [] arr, int n)
{
HashSet< int > unst1 = new HashSet< int >();
for ( int i = 0; i < n; i++)
unst1.Add(arr[i]);
int totalDist = unst1.Count;
int count = 0;
for ( int i = 0; i < n; i++) {
HashSet< int > unst = new HashSet< int >();
for ( int j = i; j < n; j++) {
unst.Add(arr[j]);
if (unst.Count == totalDist)
count++;
}
}
return count;
}
public static void Main( string [] args)
{
int [] arr = { 2, 1, 3, 2, 3 };
int n = arr.Length;
Console.WriteLine(countDistictSubarray(arr, n));
}
}
|
Javascript
function countDistinctSubarray(arr, n) {
const unst1 = new Set(arr);
const totalDist = unst1.size;
let count = 0;
for (let i = 0; i < n; i++) {
const unst = new Set();
for (let j = i; j < n; j++) {
unst.add(arr[j]);
if (unst.size === totalDist) {
count += 1;
}
}
}
return count;
}
const arr = [2, 1, 3, 2, 3];
const n = arr.length;
console.log(countDistinctSubarray(arr, n));
|
Time Complexity: O(n*n)
Auxiliary Space: O(n)
An efficient approach is to use a sliding window to count all distinct elements in one iteration.
- Find the number of distinct elements in the entire array. Let this number be k <= N. Initialize Left = 0, Right = 0 and window = 0.
- Increment right until the number of distinct elements in the range [Left=0, Right] is equal to k(or window size would not equal to k), let this right be R1. Now, since the sub-array [Left = 0, R1] has k distinct elements, so all the sub-arrays starting at Left = 0 and ending after R1 will also have k distinct elements. Thus, add N-R1+1 to the answer because [Left.. R1], [Left.. R1+1], [Left.. R1+2] … [Left.. N-1] contains all the distinct numbers.
- Now keeping R1 same, increment left. Decrease the frequency of the previous element i.e., arr[0], and if its frequency becomes 0, decrease the window size. Now, the sub-array is [Left = 1, Right = R1].
- Repeat the same process from step 2 for other values of Left and Right till Left < N.
Implementation:
C++
#include<bits/stdc++.h>
using namespace std;
int countDistictSubarray( int arr[], int n)
{
unordered_map< int , int > vis;
for ( int i = 0; i < n; ++i)
vis[arr[i]] = 1;
int k = vis.size();
vis.clear();
int ans = 0, right = 0, window = 0;
for ( int left = 0; left < n; ++left)
{
while (right < n && window < k)
{
++vis[ arr[right] ];
if (vis[ arr[right] ] == 1)
++window;
++right;
}
if (window == k)
ans += (n - right + 1);
--vis[ arr[left] ];
if (vis[ arr[left] ] == 0)
--window;
}
return ans;
}
int main()
{
int arr[] = {2, 1, 3, 2, 3};
int n = sizeof (arr) / sizeof (arr[0]);
cout << countDistictSubarray(arr, n) << "n" ;
return 0;
}
|
Java
import java.util.HashMap;
class Test
{
static int countDistictSubarray( int arr[], int n)
{
HashMap<Integer, Integer> vis = new HashMap<Integer,Integer>(){
@Override
public Integer get(Object key) {
if (!containsKey(key))
return 0 ;
return super .get(key);
}
};
for ( int i = 0 ; i < n; ++i)
vis.put(arr[i], 1 );
int k = vis.size();
vis.clear();
int ans = 0 , right = 0 , window = 0 ;
for ( int left = 0 ; left < n; ++left)
{
while (right < n && window < k)
{
vis.put(arr[right], vis.get(arr[right]) + 1 );
if (vis.get(arr[right])== 1 )
++window;
++right;
}
if (window == k)
ans += (n - right + 1 );
vis.put(arr[left], vis.get(arr[left]) - 1 );
if (vis.get(arr[left]) == 0 )
--window;
}
return ans;
}
public static void main(String args[])
{
int arr[] = { 2 , 1 , 3 , 2 , 3 };
System.out.println(countDistictSubarray(arr, arr.length));
}
}
|
Python3
def countDistictSubarray(arr, n):
vis = dict ()
for i in range (n):
vis[arr[i]] = 1
k = len (vis)
vid = dict ()
ans = 0
right = 0
window = 0
for left in range (n):
while (right < n and window < k):
if arr[right] in vid.keys():
vid[ arr[right] ] + = 1
else :
vid[ arr[right] ] = 1
if (vid[ arr[right] ] = = 1 ):
window + = 1
right + = 1
if (window = = k):
ans + = (n - right + 1 )
vid[ arr[left] ] - = 1
if (vid[ arr[left] ] = = 0 ):
window - = 1
return ans
arr = [ 2 , 1 , 3 , 2 , 3 ]
n = len (arr)
print (countDistictSubarray(arr, n))
|
C#
using System;
using System.Collections.Generic;
class Test
{
static int countDistictSubarray( int []arr, int n)
{
Dictionary< int , int > vis = new Dictionary< int , int >();
for ( int i = 0; i < n; ++i)
if (!vis.ContainsKey(arr[i]))
vis.Add(arr[i], 1);
int k = vis.Count;
vis.Clear();
int ans = 0, right = 0, window = 0;
for ( int left = 0; left < n; ++left)
{
while (right < n && window < k)
{
if (vis.ContainsKey(arr[right]))
vis[arr[right]] = vis[arr[right]] + 1;
else
vis.Add(arr[right], 1);
if (vis[arr[right]] == 1)
++window;
++right;
}
if (window == k)
ans += (n - right + 1);
if (vis.ContainsKey(arr[left]))
vis[arr[left]] = vis[arr[left]] - 1;
if (vis[arr[left]] == 0)
--window;
}
return ans;
}
public static void Main(String []args)
{
int []arr = {2, 1, 3, 2, 3};
Console.WriteLine(countDistictSubarray(arr, arr.Length));
}
}
|
Javascript
<script>
function countDistictSubarray(arr,n)
{
let vis = new Map();
for (let i = 0; i < n; ++i)
vis.set(arr[i], 1);
let k = vis.size;
let vid= new Map();
let ans = 0, right = 0, window = 0;
for (let left = 0; left < n; left++)
{
while (right < n && window < k)
{
if (vid.has(arr[right]))
vid.set(arr[right], vid.get(arr[right]) + 1);
else
vid.set(arr[right], 1);
if (vid.get(arr[right])== 1)
window++;
right++;
}
if (window == k)
ans += (n - right + 1);
if (vid.has(arr[left]))
vid.set(arr[left], vid.get(arr[left])- 1);
if (vid.get(arr[left]) == 0)
--window;
}
return ans;
}
let arr=[2, 1, 3, 2, 3];
document.write(countDistictSubarray(arr, arr.length));
</script>
|
Time complexity: O(n)
Auxiliary space: O(n)
If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
09 Mar, 2023
Like Article
Save Article