Open In App

Sum of Count of Unique Numbers in all Subarrays

Last Updated : 12 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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)


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++




// 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();


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 map, 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);


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)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads