Sum of Count of Unique Numbers in all Subarrays
Last Updated :
12 Jan, 2024
Given an array of n integers, the task is to count the sum of unique numbers in all subarrays.
Examples:
Input: [2, 1, 2]
Output: 9
Explanation: There are total 6 subarrays which are [2], [2, 1], [2, 1, 2], [1], [1, 2], [2]. The count of unique numbers in these subarrays is 1, 2, 2, 1, 2, 1 respectively. The sum of count these numbers will be 9.
Input: [2, 1, 3, 2]
Output: 19
Naive approach: The basic way to solve the problem is as follows:
The idea is to generate all the subarrays and for each subarray count the unique numbers and calculate its sum. The unique numbers in each subarray can be computed with help of map.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int uniqueElementSubarray(vector< int >& a, int l, int r)
{
unordered_map< int , int > mp;
int count = 0;
for ( int i = l; i <= r; i++) {
mp[a[i]]++;
if (mp[a[i]] == 1) {
count++;
}
}
return count;
}
int countUniqueElements(vector< int > a)
{
int n = a.size();
int res = 0;
for ( int i = 0; i < n; i++) {
for ( int j = i; j < n; j++) {
res = res + uniqueElementSubarray(a, i, j);
}
}
return res;
}
int main()
{
int n = 4;
vector< int > a{ 2, 1, 3, 2 };
int ans = countUniqueElements(a);
cout << "Sum of Count of Unique Numbers in all "
"Subarrays: "
<< ans;
return 0;
}
|
Java
import java.util.*;
public class UniqueElementSubarray {
public static int uniqueElementSubarray( int [] a, int l, int r) {
Map<Integer, Integer> mp = new HashMap<>();
int count = 0 ;
for ( int i = l; i <= r; i++) {
mp.put(a[i], mp.getOrDefault(a[i], 0 ) + 1 );
if (mp.get(a[i]) == 1 ) {
count++;
}
}
return count;
}
public static int countUniqueElements( int [] a) {
int n = a.length;
int res = 0 ;
for ( int i = 0 ; i < n; i++) {
for ( int j = i; j < n; j++) {
res += uniqueElementSubarray(a, i, j);
}
}
return res;
}
public static void main(String[] args) {
int [] a = { 2 , 1 , 3 , 2 };
int ans = countUniqueElements(a);
System.out.println( "Sum of Count of Unique Numbers in all Subarrays: " + ans);
}
}
|
Python3
def uniqueElementSubarray(a, l, r):
mp = {}
count = 0
for i in range (l, r + 1 ):
mp[a[i]] = mp.get(a[i], 0 ) + 1
if mp[a[i]] = = 1 :
count + = 1
return count
def countUniqueElements(a):
n = len (a)
res = 0
for i in range (n):
for j in range (i, n):
res + = uniqueElementSubarray(a, i, j)
return res
n = 4
a = [ 2 , 1 , 3 , 2 ]
ans = countUniqueElements(a)
print ( "Sum of Count of Unique Numbers in all Subarrays:" , ans)
|
C#
using System;
using System.Collections.Generic;
class Program {
static int UniqueElementSubarray(List< int > a, int l,
int r)
{
Dictionary< int , int > mp
= new Dictionary< int , int >();
int count = 0;
for ( int i = l; i <= r; i++) {
if (!mp.ContainsKey(a[i]))
mp[a[i]] = 0;
mp[a[i]]++;
if (mp[a[i]] == 1)
count++;
}
return count;
}
static int CountUniqueElements(List< int > a)
{
int res = 0;
for ( int i = 0; i < a.Count; i++) {
for ( int j = i; j < a.Count; j++) {
res = res + UniqueElementSubarray(a, i, j);
}
}
return res;
}
static void Main()
{
List< int > a = new List< int >{ 2, 1, 3, 2 };
int ans = CountUniqueElements(a);
Console.WriteLine(
"Sum of Count of Unique Numbers in all Subarrays: "
+ ans);
}
}
|
Javascript
function uniqueElementSubarray(a, l, r) {
let mp = {};
let count = 0;
for (let i = l; i <= r; i++) {
mp[a[i]] = mp[a[i]] ? mp[a[i]] + 1 : 1;
if (mp[a[i]] === 1) {
count += 1;
}
}
return count;
}
function countUniqueElements(a) {
let n = a.length;
let res = 0;
for (let i = 0; i < n; i++) {
for (let j = i; j < n; j++) {
res += uniqueElementSubarray(a, i, j);
}
}
return res;
}
let n = 4;
let a = [2, 1, 3, 2];
let ans = countUniqueElements(a);
console.log( "Sum of Count of Unique Numbers in all Subarrays:" , ans);
|
Output
Sum of Count of Unique Numbers in all Subarrays: 19
Time Complexity: O(n^3) since we are processing n^2 subarrays with maximum length n.
Auxiliary Space: O(n)
Better Approach: To solve the problem follow the below idea:
For each index i, find the the sum of unique elements of all subarrays starting at index i . This can be done by starting at index i, and iterating until the end of the array, keep updating the number of unique elements accordingly and store its sum. Then add this sum to final answer for each i from 1 to n.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int countUniqueElements(vector< int > a)
{
int n = a.size();
int res = 0;
for ( int i = 0; i < n; i++) {
unordered_map< int , int > mp;
int count = 0;
int sum = 0;
for ( int j = i; j < n; j++) {
mp[a[j]]++;
if (mp[a[j]] == 1)
count++;
sum = sum + count;
}
res = res + sum;
}
return res;
}
int main()
{
int n = 4;
vector< int > a{ 2, 1, 3, 2 };
int ans = countUniqueElements(a);
cout << "Sum of Count of Unique Numbers in all "
"Subarrays: "
<< ans;
return 0;
}
|
Java
import java.util.HashMap;
public class UniqueNumbersInSubarrays {
public static int countUniqueElements( int [] a) {
int n = a.length;
int res = 0 ;
for ( int i = 0 ; i < n; i++) {
HashMap<Integer, Integer> map = new HashMap<>();
int count = 0 ;
int sum = 0 ;
for ( int j = i; j < n; j++) {
int currentElement = a[j];
if (!map.containsKey(currentElement)) {
map.put(currentElement, 1 );
count++;
}
sum = sum + count;
}
res = res + sum;
}
return res;
}
public static void main(String[] args) {
int [] a = { 2 , 1 , 3 , 2 };
int ans = countUniqueElements(a);
System.out.println( "Sum of Count of Unique Numbers in all Subarrays: " + ans);
}
}
|
Python3
def countUniqueElements(a):
n = len (a)
res = 0
for i in range (n):
mp = {}
count = 0
sum_unique = 0
for j in range (i, n):
mp[a[j]] = mp.get(a[j], 0 ) + 1
if mp[a[j]] = = 1 :
count + = 1
sum_unique + = count
res + = sum_unique
return res
n = 4
a = [ 2 , 1 , 3 , 2 ]
ans = countUniqueElements(a)
print (f "Sum of Count of Unique Numbers in all Subarrays: {ans}" )
|
C#
using System;
using System.Collections.Generic;
class Program
{
static int CountUniqueElements(List< int > a)
{
int res = 0;
for ( int i = 0; i < a.Count; i++)
{
Dictionary< int , int > mp = new Dictionary< int , int >();
int count = 0;
int sum = 0;
for ( int j = i; j < a.Count; j++)
{
if (!mp.ContainsKey(a[j]))
{
mp[a[j]] = 1;
count++;
}
sum += count;
}
res += sum;
}
return res;
}
static void Main()
{
List< int > a = new List< int > { 2, 1, 3, 2 };
int ans = CountUniqueElements(a);
Console.WriteLine( "Sum of Count of Unique Numbers in all Subarrays: " + ans);
}
}
|
Javascript
function countUniqueElements(arr) {
let res = 0;
for (let i = 0; i < arr.length; i++) {
let mp = new Map();
let count = 0;
let sum = 0;
for (let j = i; j < arr.length; j++) {
if (!mp.has(arr[j])) {
mp.set(arr[j], 1);
count++;
}
sum += count;
}
res += sum;
}
return res;
}
function main() {
let a = [2, 1, 3, 2];
let ans = countUniqueElements(a);
console.log( "Sum of Count of Unique Numbers in all Subarrays: " + ans);
}
main();
|
Output
Sum of Count of Unique Numbers in all Subarrays: 19
Time Complexity: O(n^2), (The outer loop runs in O(n) time, and the inner loop runs in O(n), resulting in a total time complexity of O(n^2).)
Auxiliary Space: O(n)
Efficient Approach: To solve the problem efficiently follow the below idea:
For any element x in the array, the contribution of this element will be the number of subarrays in which the frequency of this element is atleast 1. Coversely, this will be equal to total subarrays minus the number of subarrays in x is not present. This contribution is added to the overall answer. By repeating the process for all elements, sum of unique numbers in all subarrays can be computed.
Follow the steps below to solve the problem:
- For each unique element in the array: store the indexes at which the element appears.
- Indexes of each element can be stored in a map of arrays.
- For each element
x
in the m
ap, let arr represent the array of indexes of x:
- Calculate the contribution of
x
to the final answer using the formula:
contribution = totalSubarrays -
(sum of ((index difference * (index difference + 1)) / 2) ),
where index difference is (arr[j]-arr[j-1]-1) for j ranges from 1 to size of arr array.
- Add the contribution of the element to the final answer.
- The Sum of contributions calculated is the final answer, representing the sum of unique numbers in all subarrays.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int countUniqueElements(vector< int > a)
{
int n = a.size();
int total_subarrays = n * (n + 1) / 2;
int res = 0;
unordered_map< int , vector< int > > mp;
for ( int i = 0; i < n; i++) {
mp[a[i]].push_back(i);
}
for ( auto x : mp) {
vector< int > arr = x.second;
arr.push_back(n);
int len = arr.size();
int contribution = 0;
int p = -1;
for ( int j = 0; j < len; j++) {
int index_difference = arr[j] - p - 1;
contribution += (index_difference
* (index_difference + 1))
/ 2;
p = arr[j];
}
res = res + (total_subarrays - contribution);
}
return res;
}
int main()
{
int n = 4;
vector< int > a{ 2, 1, 3, 2 };
int ans = countUniqueElements(a);
cout << "Sum of Count of Unique Numbers in all "
"Subarrays: "
<< ans;
return 0;
}
|
Java
import java.util.*;
public class UniqueNumbersSubarrays {
public static int countUniqueElements(ArrayList<Integer> a) {
int n = a.size();
int totalSubarrays = n * (n + 1 ) / 2 ;
int res = 0 ;
HashMap<Integer, ArrayList<Integer>> mp = new HashMap<>();
for ( int i = 0 ; i < n; i++) {
if (!mp.containsKey(a.get(i))) {
mp.put(a.get(i), new ArrayList<>());
}
mp.get(a.get(i)).add(i);
}
for (Map.Entry<Integer, ArrayList<Integer>> entry : mp.entrySet()) {
ArrayList<Integer> arr = entry.getValue();
arr.add(n);
int len = arr.size();
int contribution = 0 ;
int p = - 1 ;
for ( int j = 0 ; j < len; j++) {
int indexDifference = arr.get(j) - p - 1 ;
contribution += (indexDifference * (indexDifference + 1 )) / 2 ;
p = arr.get(j);
}
res += (totalSubarrays - contribution);
}
return res;
}
public static void main(String[] args) {
int n = 4 ;
ArrayList<Integer> a = new ArrayList<>(Arrays.asList( 2 , 1 , 3 , 2 ));
int ans = countUniqueElements(a);
System.out.println( "Sum of Count of Unique Numbers in all Subarrays: " + ans);
}
}
|
Python3
from collections import defaultdict
def count_unique_elements(a):
n = len (a)
total_subarrays = n * (n + 1 ) / / 2
res = 0
mp = defaultdict( list )
for i in range (n):
mp[a[i]].append(i)
for x in mp.items():
arr = x[ 1 ]
arr.append(n)
length = len (arr)
contribution = 0
p = - 1
for j in range (length):
index_difference = arr[j] - p - 1
contribution + = (index_difference
* (index_difference + 1 )) / / 2
p = arr[j]
res = res + (total_subarrays - contribution)
return res
if __name__ = = "__main__" :
n = 4
a = [ 2 , 1 , 3 , 2 ]
ans = count_unique_elements(a)
print ( "Sum of Count of Unique Numbers in all Subarrays:" , ans)
|
C#
using System;
using System.Collections.Generic;
class UniqueNumbersSubarrays
{
static int CountUniqueElements(List< int > a)
{
int n = a.Count;
int totalSubarrays = n * (n + 1) / 2;
int res = 0;
Dictionary< int , List< int >> mp = new Dictionary< int , List< int >>();
for ( int i = 0; i < n; i++)
{
if (!mp.ContainsKey(a[i]))
mp[a[i]] = new List< int >();
mp[a[i]].Add(i);
}
foreach ( var x in mp)
{
List< int > arr = x.Value;
arr.Add(n);
int len = arr.Count;
int contribution = 0;
int p = -1;
for ( int j = 0; j < len; j++)
{
int indexDifference = arr[j] - p - 1;
contribution += (indexDifference * (indexDifference + 1)) / 2;
p = arr[j];
}
res = res + (totalSubarrays - contribution);
}
return res;
}
static void Main()
{
List< int > a = new List< int > { 2, 1, 3, 2 };
int ans = CountUniqueElements(a);
Console.WriteLine($ "Sum of Count of Unique Numbers in all Subarrays: {ans}" );
}
}
|
Javascript
function countUniqueElements(a) {
const n = a.length;
const totalSubarrays = (n * (n + 1)) / 2;
let res = 0;
const mp = new Map();
for (let i = 0; i < n; i++) {
if (!mp.has(a[i])) {
mp.set(a[i], []);
}
mp.get(a[i]).push(i);
}
for (const [num, indexes] of mp) {
const arr = [...indexes, n];
const length = arr.length;
let contribution = 0;
let p = -1;
for (let j = 0; j < length; j++) {
const indexDifference = arr[j] - p - 1;
contribution += (indexDifference * (indexDifference + 1)) / 2;
p = arr[j];
}
res += totalSubarrays - contribution;
}
return res;
}
const n = 4;
const a = [2, 1, 3, 2];
const ans = countUniqueElements(a);
console.log( "Sum of Count of Unique Numbers in all Subarrays:" , ans);
|
Output
Sum of Count of Unique Numbers in all Subarrays: 19
Time Complexity: O(n), since iteration of indexes of elements is done only once.
Auxiliary Space: O(n)
Share your thoughts in the comments
Please Login to comment...