Subarrays with distinct elements
Given an array, the task is to calculate the sum of lengths of contiguous subarrays having all elements distinct.
Examples:
Input : arr[] = {1, 2, 3}
Output : 10
{1, 2, 3} is a subarray of length 3 with
distinct elements. Total length of length
three = 3.
{1, 2}, {2, 3} are 2 subarray of length 2
with distinct elements. Total length of
lengths two = 2 + 2 = 4
{1}, {2}, {3} are 3 subarrays of length 1
with distinct element. Total lengths of
length one = 1 + 1 + 1 = 3
Sum of lengths = 3 + 4 + 3 = 10
Input : arr[] = {1, 2, 1}
Output : 7
Input : arr[] = {1, 2, 3, 4}
Output : 20
A simple solution is to consider all subarrays and for every subarray check if it has distinct elements or not using hashing. And add lengths of all subarrays having distinct elements. If we use hashing to find distinct elements, then this approach takes O(n2) time under the assumption that hashing search and insert operations take O(1) time.
An efficient solution is based on the fact that if we know all elements in a subarray arr[i..j] are distinct, sum of all lengths of distinct element subarrays in this subarray is ((j-i+1)*(j-i+2))/2. How? the possible lengths of subarrays are 1, 2, 3,……, j – i +1. So, the sum will be ((j – i +1)*(j – i +2))/2.
We first find the largest subarray (with distinct elements) starting from first element. We count sum of lengths in this subarray using above formula. For finding next subarray of the distinct element, we increment starting point, i and ending point, j unless (i+1, j) are distinct. If not possible, then we increment i again and move forward the same way.
Below is the implementation of this approach:
C++
#include<bits/stdc++.h>
using namespace std;
int sumoflength( int arr[], int n)
{
unordered_set< int > s;
int j = 0, ans = 0;
for ( int i=0; i<n; i++)
{
while (j < n && s.find(arr[j]) == s.end())
{
s.insert(arr[j]);
j++;
}
ans += ((j - i) * (j - i + 1))/2;
s.erase(arr[i]);
}
return ans;
}
int main()
{
int arr[] = {1, 2, 3, 4};
int n = sizeof (arr)/ sizeof (arr[0]);
cout << sumoflength(arr, n) << endl;
return 0;
}
|
Java
import java.util.*;
class geeks
{
public static int sumoflength( int [] arr, int n)
{
Set<Integer> s = new HashSet<>();
int j = 0 , ans = 0 ;
for ( int i = 0 ; i < n; i++)
{
while (j < n && !s.contains(arr[j]))
{
s.add(arr[j]);
j++;
}
ans += ((j - i) * (j - i + 1 )) / 2 ;
s.remove(arr[i]);
}
return ans;
}
public static void main(String[] args)
{
int [] arr = { 1 , 2 , 3 , 4 };
int n = arr.length;
System.out.println(sumoflength(arr, n));
}
}
|
Python 3
def sumoflength(arr, n):
s = []
j = 0
ans = 0
for i in range (n):
while (j < n and (arr[j] not in s)):
s.append(arr[j])
j + = 1
ans + = ((j - i) * (j - i + 1 )) / / 2
s.remove(arr[i])
return ans
if __name__ = = "__main__" :
arr = [ 1 , 2 , 3 , 4 ]
n = len (arr)
print (sumoflength(arr, n))
|
C#
using System;
using System.Collections.Generic;
public class geeks
{
public static int sumoflength( int [] arr, int n)
{
HashSet< int > s = new HashSet< int >();
int j = 0, ans = 0;
for ( int i = 0; i < n; i++)
{
while (j < n && !s.Contains(arr[j]))
{
s.Add(arr[j]);
j++;
}
ans += ((j - i) * (j - i + 1)) / 2;
s.Remove(arr[i]);
}
return ans;
}
public static void Main(String[] args)
{
int [] arr = { 1, 2, 3, 4 };
int n = arr.Length;
Console.WriteLine(sumoflength(arr, n));
}
}
|
Javascript
<script>
function sumoflength(arr,n)
{
let s= new Set();
let j = 0, ans = 0;
for (let i = 0; i < n; i++)
{
while (j < n && !s.has(arr[j]))
{
s.add(arr[i]);
j++;
}
ans += Math.floor(((j - i) * (j - i + 1)) / 2);
s. delete (arr[i]);
}
return ans;
}
let arr=[1, 2, 3, 4];
let n = arr.length;
document.write(sumoflength(arr, n));
</script>
|
Time Complexity: O(n). Note that the inner loop runs n times in total as j goes from 0 to n across all outer loops. So we do O(2n) operations which is same as O(n).
Space Complexity: O(n), since n extra space has been added
Last Updated :
19 Sep, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...