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++
// C++ program to find Sum of Count of Unique Numbers in all
// Subarrays
#include <bits/stdc++.h>
using namespace std;
// This function returns numbers of unique elements for
// subarray a[l...r]
int uniqueElementSubarray(vector<int>& a, int l, int r)
{
// To store frequency
unordered_map<int, int> mp;
// To count unique elements
int count = 0;
for (int i = l; i <= r; i++) {
mp[a[i]]++;
if (mp[a[i]] == 1) {
count++;
}
}
return count;
}
// Returns Sum of Count of Unique Numbers in all
// Subarrays
int countUniqueElements(vector<int> a)
{
int n = a.size();
// To store final answer
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
// Count the number of unqiue elements from
// index i to index j and add to result.
res = res + uniqueElementSubarray(a, i, j);
}
}
return res;
}
// Driver code
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 {
// This function returns the count of unique elements for subarray a[l...r]
public static int uniqueElementSubarray(int[] a, int l, int r) {
// To store frequency
Map<Integer, Integer> mp = new HashMap<>();
// To count unique elements
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;
}
// Returns the sum of the count of unique numbers in all subarrays
public static int countUniqueElements(int[] a) {
int n = a.length;
// To store the final answer
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
// Count the number of unique elements from
// index i to index j and add to the result.
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);
}
}
//Contributed by Aditi Tyagi
Python3
# Python program to find Sum of Count of Unique Numbers in all
# Subarrays
# This function returns numbers of unique elements for
# subarray a[l...r]
def uniqueElementSubarray(a, l, r):
# To store frequency
mp = {}
# To count unique elements
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
# Returns Sum of Count of Unique Numbers in all
# Subarrays
def countUniqueElements(a):
n = len(a)
# To store final answer
res = 0
for i in range(n):
for j in range(i, n):
# Count the number of unqiue elements from
# index i to index j and add to result.
res += uniqueElementSubarray(a, i, j)
return res
# Driver code
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 {
// This function returns the number of unique elements
// for a subarray a[l...r]
static int UniqueElementSubarray(List<int> a, int l,
int r)
{
// To store frequency
Dictionary<int, int> mp
= new Dictionary<int, int>();
// To count unique elements
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;
}
// Returns the sum of Count of Unique Numbers in all
// Subarrays
static int CountUniqueElements(List<int> a)
{
// To store the final answer
int res = 0;
for (int i = 0; i < a.Count; i++) {
for (int j = i; j < a.Count; j++) {
// Count the number of unique elements from
// index i to index j and add to result.
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
// JavaScript program to find Sum of Count of Unique Numbers in all
// Subarrays
// This function returns numbers of unique elements for
// subarray a[l...r]
function uniqueElementSubarray(a, l, r) {
// To store frequency
let mp = {};
// To count unique elements
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;
}
// Returns Sum of Count of Unique Numbers in all
// Subarrays
function countUniqueElements(a) {
let n = a.length;
// To store final answer
let res = 0;
for (let i = 0; i < n; i++) {
for (let j = i; j < n; j++) {
// Count the number of unique elements from
// index i to index j and add to result.
res += uniqueElementSubarray(a, i, j);
}
}
return res;
}
// Driver code
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);
// This code is contributed by Tapesh(tapeshdua420)
OutputSum 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++
// C++ program to find Sum of Count of Unique
// Numbers in all Subarrays
#include <bits/stdc++.h>
using namespace std;
// Returns Sum of Count of Unique Numbers
// in all Subarrays
int countUniqueElements(vector<int> a)
{
int n = a.size();
// To store final answer
int res = 0;
for (int i = 0; i < n; i++) {
// To store frequency
unordered_map<int, int> mp;
// To store number of unique elements
int count = 0;
// To store sum of unique numbers of
// all subbrays starting at index i.
int sum = 0;
for (int j = i; j < n; j++) {
mp[a[j]]++;
if (mp[a[j]] == 1)
count++;
sum = sum + count;
}
// Add sum of unique numbers of all
// subarrays starting at index i
// to final answer
res = res + sum;
}
return res;
}
// Driver code
int main()
{
int n = 4;
vector<int> a{ 2, 1, 3, 2 };
int ans = countUniqueElements(a);
// Function Call
cout << "Sum of Count of Unique Numbers in all "
"Subarrays: "
<< ans;
return 0;
}
Java
import java.util.HashMap;
public class UniqueNumbersInSubarrays {
// Returns Sum of Count of Unique Numbers in all Subarrays
public static int countUniqueElements(int[] a) {
int n = a.length;
// To store the final answer
int res = 0;
for (int i = 0; i < n; i++) {
// To store frequency
HashMap<Integer, Integer> map = new HashMap<>();
// To store the number of unique elements
int count = 0;
// To store the sum of unique numbers of all subarrays starting at index i.
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;
}
// Add the sum of unique numbers of all subarrays starting at index i to the final answer
res = res + sum;
}
return res;
}
public static void main(String[] args) {
int[] a = {2, 1, 3, 2};
int ans = countUniqueElements(a);
// Function Call
System.out.println("Sum of Count of Unique Numbers in all Subarrays: " + ans);
}
}
Python3
def countUniqueElements(a):
n = len(a)
# To store final answer
res = 0
for i in range(n):
# To store frequency
mp = {}
# To store number of unique elements
count = 0
# To store sum of unique numbers of
# all subarrays starting at index i.
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
# Add sum of unique numbers of all
# subarrays starting at index i
# to final answer
res += sum_unique
return res
# Driver code
n = 4
a = [2, 1, 3, 2]
ans = countUniqueElements(a)
# Function Call
print(f"Sum of Count of Unique Numbers in all Subarrays: {ans}")
C#
using System;
using System.Collections.Generic;
class Program
{
// Returns Sum of Count of Unique Numbers
// in all Subarrays
static int CountUniqueElements(List<int> a)
{
// To store final answer
int res = 0;
for (int i = 0; i < a.Count; i++)
{
// To store frequency
Dictionary<int, int> mp = new Dictionary<int, int>();
// To store the number of unique elements
int count = 0;
// To store sum of unique numbers of
// all subarrays starting at index i.
int sum = 0;
for (int j = i; j < a.Count; j++)
{
if (!mp.ContainsKey(a[j]))
{
mp[a[j]] = 1;
count++;
}
sum += count;
}
// Add the sum of unique numbers of all
// subarrays starting at index i
// to the final answer
res += sum;
}
return res;
}
static void Main()
{
List<int> a = new List<int> { 2, 1, 3, 2 };
int ans = CountUniqueElements(a);
// Function Call
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;
}
// Main function
function main() {
let a = [2, 1, 3, 2];
let ans = countUniqueElements(a);
// Function Call
console.log("Sum of Count of Unique Numbers in all Subarrays: " + ans);
}
// Execute the main function
main();
OutputSum 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++
// C++ program to find Sum of Count of Unique
// Numbers in all Subarrays
#include <bits/stdc++.h>
using namespace std;
// Returns Sum of Count of Unique Numbers
// in all Subarrays
int countUniqueElements(vector<int> a)
{
int n = a.size();
int total_subarrays = n * (n + 1) / 2;
// To store final answer
int res = 0;
// To store indexes of each element
unordered_map<int, vector<int> > mp;
// Iterate the array to store the index
for (int i = 0; i < n; i++) {
mp[a[i]].push_back(i);
}
// Iterate over the map to find the
// contribution of each unique element
for (auto x : mp) {
// Stores the indexes of element x
vector<int> arr = x.second;
arr.push_back(n);
// Stores the length of index array
int len = arr.size();
// To find contribution of element x
// in the final answer
int contribution = 0;
// To store previous index of element x
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];
}
// Add contribution of each unique element
// to final answer
res = res + (total_subarrays - contribution);
}
return res;
}
// Driver code
int main()
{
int n = 4;
vector<int> a{ 2, 1, 3, 2 };
int ans = countUniqueElements(a);
// Function Call
cout << "Sum of Count of Unique Numbers in all "
"Subarrays: "
<< ans;
return 0;
}
Java
import java.util.*;
public class UniqueNumbersSubarrays {
// Returns Sum of Count of Unique Numbers in all Subarrays
public static int countUniqueElements(ArrayList<Integer> a) {
int n = a.size();
int totalSubarrays = n * (n + 1) / 2;
// To store final answer
int res = 0;
// To store indexes of each element
HashMap<Integer, ArrayList<Integer>> mp = new HashMap<>();
// Iterate the array to store the index
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);
}
// Iterate over the map to find the contribution of each unique element
for (Map.Entry<Integer, ArrayList<Integer>> entry : mp.entrySet()) {
ArrayList<Integer> arr = entry.getValue();
arr.add(n);
// Stores the length of index array
int len = arr.size();
// To find contribution of element x in the final answer
int contribution = 0;
// To store previous index of element x
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);
}
// Add contribution of each unique element to final answer
res += (totalSubarrays - contribution);
}
return res;
}
// Driver code
public static void main(String[] args) {
int n = 4;
ArrayList<Integer> a = new ArrayList<>(Arrays.asList(2, 1, 3, 2));
int ans = countUniqueElements(a);
// Function Call
System.out.println("Sum of Count of Unique Numbers in all Subarrays: " + ans);
}
}
Python3
from collections import defaultdict
# Returns Sum of Count of Unique Numbers
# in all Subarrays
def count_unique_elements(a):
n = len(a)
total_subarrays = n * (n + 1) // 2
# To store final answer
res = 0
# To store indexes of each element
mp = defaultdict(list)
# Iterate the array to store the index
for i in range(n):
mp[a[i]].append(i)
# Iterate over the map to find the
# contribution of each unique element
for x in mp.items():
# Stores the indexes of element x
arr = x[1]
arr.append(n)
# Stores the length of the index array
length = len(arr)
# To find the contribution of element x
# in the final answer
contribution = 0
# To store the previous index of element x
p = -1
for j in range(length):
index_difference = arr[j] - p - 1
contribution += (index_difference
* (index_difference + 1)) // 2
p = arr[j]
# Add the contribution of each unique element
# to the final answer
res = res + (total_subarrays - contribution)
return res
# Driver code
if __name__ == "__main__":
n = 4
a = [2, 1, 3, 2]
ans = count_unique_elements(a)
# Function Call
print("Sum of Count of Unique Numbers in all Subarrays:", ans)
C#
using System;
using System.Collections.Generic;
class UniqueNumbersSubarrays
{
// Function to count unique elements in all subarrays
static int CountUniqueElements(List<int> a)
{
int n = a.Count; // Get the length of the list
int totalSubarrays = n * (n + 1) / 2; // Calculate the total number of subarrays
int res = 0; // To store the result
// Dictionary to store indexes of each element
Dictionary<int, List<int>> mp = new Dictionary<int, List<int>>();
// Store the indexes of each element in the dictionary
for (int i = 0; i < n; i++)
{
if (!mp.ContainsKey(a[i]))
mp[a[i]] = new List<int>();
mp[a[i]].Add(i);
}
// Iterate through the dictionary to find the contribution of each unique element
foreach (var x in mp)
{
List<int> arr = x.Value;
arr.Add(n);
int len = arr.Count;
int contribution = 0;
int p = -1;
// Calculate the contribution of each unique element in the final answer
for (int j = 0; j < len; j++)
{
int indexDifference = arr[j] - p - 1;
contribution += (indexDifference * (indexDifference + 1)) / 2;
p = arr[j];
}
// Add the contribution of each unique element to the final result
res = res + (totalSubarrays - contribution);
}
return res; // Return the final result
}
// Main method
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();
// Iterate the array to store the index
for (let i = 0; i < n; i++) {
if (!mp.has(a[i])) {
mp.set(a[i], []);
}
mp.get(a[i]).push(i);
}
// Iterate over the map to find the contribution of each unique element
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;
}
// Driver code
const n = 4;
const a = [2, 1, 3, 2];
const ans = countUniqueElements(a);
// Function Call
console.log("Sum of Count of Unique Numbers in all Subarrays:", ans);
OutputSum 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)
Similar Reads
Basics & Prerequisites
Data Structures
Array Data StructureIn this article, we introduce array, implementation in different popular languages, its basic operations and commonly seen problems / interview questions. An array stores items (in case of C/C++ and Java Primitive Arrays) or their references (in case of Python, JS, Java Non-Primitive) at contiguous
3 min read
String in Data StructureA string is a sequence of characters. The following facts make string an interesting data structure.Small set of elements. Unlike normal array, strings typically have smaller set of items. For example, lowercase English alphabet has only 26 characters. ASCII has only 256 characters.Strings are immut
2 min read
Hashing in Data StructureHashing is a technique used in data structures that efficiently stores and retrieves data in a way that allows for quick access. Hashing involves mapping data to a specific index in a hash table (an array of items) using a hash function. It enables fast retrieval of information based on its key. The
2 min read
Linked List Data StructureA linked list is a fundamental data structure in computer science. It mainly allows efficient insertion and deletion operations compared to arrays. Like arrays, it is also used to implement other data structures like stack, queue and deque. Hereâs the comparison of Linked List vs Arrays Linked List:
2 min read
Stack Data StructureA Stack is a linear data structure that follows a particular order in which the operations are performed. The order may be LIFO(Last In First Out) or FILO(First In Last Out). LIFO implies that the element that is inserted last, comes out first and FILO implies that the element that is inserted first
2 min read
Queue Data StructureA Queue Data Structure is a fundamental concept in computer science used for storing and managing data in a specific order. It follows the principle of "First in, First out" (FIFO), where the first element added to the queue is the first one to be removed. It is used as a buffer in computer systems
2 min read
Tree Data StructureTree Data Structure is a non-linear data structure in which a collection of elements known as nodes are connected to each other via edges such that there exists exactly one path between any two nodes. Types of TreeBinary Tree : Every node has at most two childrenTernary Tree : Every node has at most
4 min read
Graph Data StructureGraph Data Structure is a collection of nodes connected by edges. It's used to represent relationships between different entities. If you are looking for topic-wise list of problems on different topics like DFS, BFS, Topological Sort, Shortest Path, etc., please refer to Graph Algorithms. Basics of
3 min read
Trie Data StructureThe Trie data structure is a tree-like structure used for storing a dynamic set of strings. It allows for efficient retrieval and storage of keys, making it highly effective in handling large datasets. Trie supports operations such as insertion, search, deletion of keys, and prefix searches. In this
15+ min read
Algorithms
Searching AlgorithmsSearching algorithms are essential tools in computer science used to locate specific items within a collection of data. In this tutorial, we are mainly going to focus upon searching in an array. When we search an item in an array, there are two most common algorithms used based on the type of input
2 min read
Sorting AlgorithmsA Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read
Introduction to RecursionThe process in which a function calls itself directly or indirectly is called recursion and the corresponding function is called a recursive function. A recursive algorithm takes one step toward solution and then recursively call itself to further move. The algorithm stops once we reach the solution
14 min read
Greedy AlgorithmsGreedy algorithms are a class of algorithms that make locally optimal choices at each step with the hope of finding a global optimum solution. At every step of the algorithm, we make a choice that looks the best at the moment. To make the choice, we sometimes sort the array so that we can always get
3 min read
Graph AlgorithmsGraph is a non-linear data structure like tree data structure. The limitation of tree is, it can only represent hierarchical data. For situations where nodes or vertices are randomly connected with each other other, we use Graph. Example situations where we use graph data structure are, a social net
3 min read
Dynamic Programming or DPDynamic Programming is an algorithmic technique with the following properties.It is mainly an optimization over plain recursion. Wherever we see a recursive solution that has repeated calls for the same inputs, we can optimize it using Dynamic Programming. The idea is to simply store the results of
3 min read
Bitwise AlgorithmsBitwise algorithms in Data Structures and Algorithms (DSA) involve manipulating individual bits of binary representations of numbers to perform operations efficiently. These algorithms utilize bitwise operators like AND, OR, XOR, NOT, Left Shift, and Right Shift.BasicsIntroduction to Bitwise Algorit
4 min read
Advanced
Segment TreeSegment Tree is a data structure that allows efficient querying and updating of intervals or segments of an array. It is particularly useful for problems involving range queries, such as finding the sum, minimum, maximum, or any other operation over a specific range of elements in an array. The tree
3 min read
Pattern SearchingPattern searching algorithms are essential tools in computer science and data processing. These algorithms are designed to efficiently find a particular pattern within a larger set of data. Patten SearchingImportant Pattern Searching Algorithms:Naive String Matching : A Simple Algorithm that works i
2 min read
GeometryGeometry is a branch of mathematics that studies the properties, measurements, and relationships of points, lines, angles, surfaces, and solids. From basic lines and angles to complex structures, it helps us understand the world around us.Geometry for Students and BeginnersThis section covers key br
2 min read
Interview Preparation
Practice Problem