Sum of unique sub-array sums
Given an array of n-positive elements. The sub-array sum is defined as the sum of all elements of a particular sub-array, the task is to find the sum of all unique sub-array sum.
Note: Unique Sub-array sum means no other sub-array will have the same sum value.
Examples:
Input : arr[] = {3, 4, 5}
Output : 40
Explanation: All possible unique sub-array with their sum are as:
(3), (4), (5), (3+4), (4+5), (3+4+5). Here all are unique so required sum = 40Input : arr[] = {2, 4, 2}
Output : 12
Explanation: All possible unique sub-array with their sum are as:
(2), (4), (2), (2+4), (4+2), (2+4+2). Here only (4) and (2+4+2) are unique.
[Naive Approach] - Sorting - O(n2 Log n) Time and O(n2) Space
- Calculate the cumulative sum of an array.
- Store all sub-array sum in vector.
- Sort the vector.
- Mark all duplicate sub-array sum to zero
- Calculate and return totalSum.
#include <bits/stdc++.h>
using namespace std;
int findSubarraySum(vector<int> &arr) {
int n = arr.size();
vector<int> subArrSum;
// Generate all subarray sums and store them in a vector
for (int i = 0; i < n; i++) {
int sum = 0;
for (int j = i; j < n; j++) {
sum += arr[j];
subArrSum.push_back(sum);
}
}
// Sort the vector to group duplicate sums together
sort(subArrSum.begin(), subArrSum.end());
// Sum only unique subarray sums
int m = subArrSum.size();
int totalSum = 0;
if (m == 1) return subArrSum[0];
// Explicitely handle the first element
if (subArrSum[0] != subArrSum[1])
totalSum += subArrSum[0];
// Process Middle Elements
for (int i = 1; i < m - 1; i++) {
if (subArrSum[i] != subArrSum[i+1] &&
subArrSum[i] != subArrSum[i-1]) {
totalSum += subArrSum[i];
}
}
// Explicitely handle the last element
if (subArrSum[m-1] != subArrSum[m-2])
totalSum += subArrSum[m-1];
return totalSum;
}
int main() {
vector<int> arr = {3, 2, 3, 1, 4};
cout << findSubarraySum(arr);
return 0;
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static int findSubarraySum(int[] arr) {
int n = arr.length;
List<Integer> subArrSum = new ArrayList<>();
// Generate all subarray sums and store them in a list
for (int i = 0; i < n; i++) {
int sum = 0;
for (int j = i; j < n; j++) {
sum += arr[j];
subArrSum.add(sum);
}
}
// Sort the list to group duplicate sums together
Collections.sort(subArrSum);
// Sum only unique subarray sums
int m = subArrSum.size();
int totalSum = 0;
if (m == 1) return subArrSum.get(0);
// Explicitely handle the first element
if (!subArrSum.get(0).equals(subArrSum.get(1)))
totalSum += subArrSum.get(0);
// Process Middle Elements
for (int i = 1; i < m - 1; i++) {
if (!subArrSum.get(i).equals(subArrSum.get(i + 1)) &&
!subArrSum.get(i).equals(subArrSum.get(i - 1))) {
totalSum += subArrSum.get(i);
}
}
// Explicitely handle the last element
if (!subArrSum.get(m - 1).equals(subArrSum.get(m - 2)))
totalSum += subArrSum.get(m - 1);
return totalSum;
}
public static void main(String[] args) {
int[] arr = {3, 2, 3, 1, 4};
System.out.println(findSubarraySum(arr));
}
}
def find_subarray_sum(arr):
n = len(arr)
sub_arr_sum = []
# Generate all subarray sums and store them in a list
for i in range(n):
sum_ = 0
for j in range(i, n):
sum_ += arr[j]
sub_arr_sum.append(sum_)
# Sort the list to group duplicate sums together
sub_arr_sum.sort()
# Sum only unique subarray sums
m = len(sub_arr_sum)
total_sum = 0
if m == 1:
return sub_arr_sum[0]
# Explicitly handle the first element
if m > 1 and sub_arr_sum[0] != sub_arr_sum[1]:
total_sum += sub_arr_sum[0]
# Process Middle Elements
for i in range(1, m - 1):
if sub_arr_sum[i] != sub_arr_sum[i + 1] and sub_arr_sum[i] != sub_arr_sum[i - 1]:
total_sum += sub_arr_sum[i]
# Explicitly handle the last element
if m > 1 and sub_arr_sum[m - 1] != sub_arr_sum[m - 2]:
total_sum += sub_arr_sum[m - 1]
return total_sum
arr = [3, 2, 3, 1, 4]
print(find_subarray_sum(arr))
// C# implementation to find the sum of unique subarray sums
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static int FindSubarraySum(int[] arr)
{
int n = arr.Length;
List<int> subArrSum = new List<int>();
// Generate all subarray sums and store them in a list
for (int i = 0; i < n; i++)
{
int sum = 0;
for (int j = i; j < n; j++)
{
sum += arr[j];
subArrSum.Add(sum);
}
}
// Sort the list to group duplicate sums together
subArrSum.Sort();
// Sum only unique subarray sums
int m = subArrSum.Count;
int totalSum = 0;
if (m == 1) return subArrSum[0];
// Explicitly handle the first element
if (subArrSum[0] != subArrSum[1])
totalSum += subArrSum[0];
// Process Middle Elements
for (int i = 1; i < m - 1; i++)
{
if (subArrSum[i] != subArrSum[i + 1] &&
subArrSum[i] != subArrSum[i - 1])
{
totalSum += subArrSum[i];
}
}
// Explicitly handle the last element
if (subArrSum[m - 1] != subArrSum[m - 2])
totalSum += subArrSum[m - 1];
return totalSum;
}
static void Main()
{
int[] arr = { 3, 2, 3, 1, 4 };
Console.WriteLine(FindSubarraySum(arr));
}
}
function findSubarraySum(arr) {
let n = arr.length;
let subArrSum = [];
// Generate all subarray sums and store them in an array
for (let i = 0; i < n; i++) {
let sum = 0;
for (let j = i; j < n; j++) {
sum += arr[j];
subArrSum.push(sum);
}
}
// Sort the array to group duplicate sums together
subArrSum.sort((a, b) => a - b);
// Sum only unique subarray sums
let m = subArrSum.length;
let totalSum = 0;
if (m === 1) return subArrSum[0];
// Explicitely handle the first element
if (subArrSum[0] !== subArrSum[1])
totalSum += subArrSum[0];
// Process Middle Elements
for (let i = 1; i < m - 1; i++) {
if (subArrSum[i] !== subArrSum[i + 1] &&
subArrSum[i] !== subArrSum[i - 1]) {
totalSum += subArrSum[i];
}
}
// Explicitely handle the last element
if (subArrSum[m - 1] !== subArrSum[m - 2])
totalSum += subArrSum[m - 1];
return totalSum;
}
const arr = [3, 2, 3, 1, 4];
console.log(findSubarraySum(arr));
Output
41
[Efficient Approach] - Sorting - O(n2) Time and O(n2) Space
The idea is to make an empty hash table. We generate all subarrays. For every subarray, we compute its sum and increment count of the sum in the hash table. Finally, we add all those sums whose count is 1.
#include <bits/stdc++.h>
using namespace std;
// function for finding grandSum
long long int findSubarraySum(vector<int>& arr)
{
long long int res = 0;
// Go through all subarrays, compute sums
// and count occurrences of sums.
unordered_map<int, int> m;
int n = arr.size();
for (int i = 0; i < n; i++) {
int sum = 0;
for (int j = i; j < n; j++) {
sum += arr[j];
m[sum]++;
}
}
// Print all those sums that appear
// once.
for (auto x : m)
if (x.second == 1)
res += x.first;
return res;
}
// Driver code
int main()
{
vector<int> arr = { 3, 2, 3, 1, 4 };
cout << findSubarraySum(arr);
return 0;
}
// function for finding grandSum
import java.util.HashMap;
import java.util.Map;
public class Main {
public static int findSubarraySum(int[] arr) {
int res = 0;
// Go through all subarrays, compute sums
// and count occurrences of sums.
HashMap<Integer, Integer> m = new HashMap<>();
int n = arr.length;
for (int i = 0; i < n; i++) {
int sum = 0;
for (int j = i; j < n; j++) {
sum += arr[j];
m.put(sum, m.getOrDefault(sum, 0) + 1);
}
}
// Print all those sums that appear
// once.
for (Map.Entry<Integer, Integer> x : m.entrySet())
if (x.getValue() == 1)
res += x.getKey();
return res;
}
public static void main(String[] args) {
int[] arr = { 3, 2, 3, 1, 4 };
System.out.println(findSubarraySum(arr));
}
}
# function for finding grandSum
def find_subarray_sum(arr):
res = 0
# Go through all subarrays, compute sums
# and count occurrences of sums.
m = {}
n = len(arr)
for i in range(n):
sum = 0
for j in range(i, n):
sum += arr[j]
m[sum] = m.get(sum, 0) + 1
# Print all those sums that appear
# once.
for x in m:
if m[x] == 1:
res += x
return res
# Driver code
arr = [3, 2, 3, 1, 4]
print(find_subarray_sum(arr))
using System;
using System.Collections.Generic;
public class MainClass {
public static int FindSubarraySum(int[] arr) {
int res = 0;
// Go through all subarrays, compute sums
// and count occurrences of sums.
Dictionary<int, int> m = new Dictionary<int, int>();
int n = arr.Length;
for (int i = 0; i < n; i++) {
int sum = 0;
for (int j = i; j < n; j++) {
sum += arr[j];
if (m.ContainsKey(sum)) {
m[sum]++;
} else {
m[sum] = 1;
}
}
}
// Print all those sums that appear
// once.
foreach (var x in m) {
if (x.Value == 1)
res += x.Key;
}
return res;
}
public static void Main(string[] args) {
int[] arr = { 3, 2, 3, 1, 4 };
Console.WriteLine(FindSubarraySum(arr));
}
}
// function for finding grandSum
function findSubarraySum(arr) {
let res = 0;
// Go through all subarrays, compute sums
// and count occurrences of sums.
const m = {};
const n = arr.length;
for (let i = 0; i < n; i++) {
let sum = 0;
for (let j = i; j < n; j++) {
sum += arr[j];
m[sum] = (m[sum] || 0) + 1;
}
}
// Print all those sums that appear
// once.
for (const x in m) {
if (m[x] === 1) {
res += Number(x);
}
}
return res;
}
// Driver code
const arr = [3, 2, 3, 1, 4];
console.log(findSubarraySum(arr));
Output
41