Largest Sum Contiguous Subarray having unique elements
Given an array arr[] of N positive integers, the task is to find the subarray having maximum sum among all subarrays having unique elements and print its sum.
Input arr[] = {1, 2, 3, 3, 4, 5, 2, 1}
Output: 15
Explanation:
The subarray having maximum sum with distinct element is {3, 4, 5, 2, 1}.
Therefore, sum is = 3 + 4 + 5 + 2 + 1 = 15
Input: arr[] = {1, 2, 3, 1, 5}
Output: 11
Explanation:
The subarray having maximum sum with distinct element is {2, 3, 1, 5}.
Therefore, sum is = 2 + 3 + 1 + 5 = 11.
Naive Approach: The simplest approach to solve the problem is to generate all possible subarrays and for each subarray, check if all its elements are unique or not. Find the maximum sum among such subarrays and print it.
C++
#include <bits/stdc++.h>
using namespace std;
int maxSumSubarray( int arr[], int n)
{
int result = 0;
for ( int i = 0; i < n; i++) {
int sum = 0;
unordered_map< int , int > unmap;
for ( int j = i; j < n; j++) {
unmap[arr[j]]++;
sum += arr[j];
if (unmap.size() == (j - i + 1)) {
result = max(result, sum);
}
else {
break ;
}
}
}
return result;
}
int main()
{
int arr[] = { 1, 2, 3, 3, 4, 5, 2, 1 };
int ans = maxSumSubarray(arr, 8);
cout << (ans);
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
public static int maxSumSubarray( int arr[], int n)
{
int result = 0 ;
for ( int i = 0 ; i < n; i++) {
int sum = 0 ;
HashMap<Integer,Integer> hm= new HashMap<>();
for ( int j = i; j < n; j++) {
hm.put(arr[j],hm.getOrDefault(arr[j], 0 )+ 1 );
sum += arr[j];
if (hm.size() == (j - i + 1 )) {
result = Math.max(result, sum);
}
else {
break ;
}
}
}
return result;
}
public static void main (String[] args)
{
int arr[] = { 1 , 2 , 3 , 3 , 4 , 5 , 2 , 1 };
int ans = maxSumSubarray(arr, 8 );
System.out.println(ans);
}
}
|
Python3
from collections import defaultdict
def maxSumSubarray(arr, n):
result = 0
for i in range (n):
sum = 0
unmap = defaultdict( int )
for j in range (i, n):
unmap[arr[j]] + = 1
sum + = arr[j]
if len (unmap) = = (j - i + 1 ):
result = max (result, sum )
else :
break
return result
arr = [ 1 , 2 , 3 , 3 , 4 , 5 , 2 , 1 ]
ans = maxSumSubarray(arr, 8 )
print (ans)
|
C#
using System;
using System.Collections.Generic;
class GFG {
public static int maxSumSubarray( int [] arr, int n)
{
int result = 0;
for ( int i = 0; i < n; i++) {
int sum = 0;
Dictionary< int , int > hm
= new Dictionary< int , int >();
for ( int j = i; j < n; j++) {
if (hm.ContainsKey(arr[j])) {
hm[arr[j]]++;
}
else {
hm[arr[j]] = 1;
}
sum += arr[j];
if (hm.Count == (j - i + 1)) {
result = Math.Max(result, sum);
}
else {
break ;
}
}
}
return result;
}
public static void Main( string [] args)
{
int [] arr = { 1, 2, 3, 3, 4, 5, 2, 1 };
int ans = maxSumSubarray(arr, 8);
Console.WriteLine(ans);
}
}
|
Javascript
function maxSumSubarray( arr, n)
{
let result = 0;
for (let i = 0; i < n; i++) {
let sum = 0;
unmap= new Map();
for (let j = i; j < n; j++) {
if (unmap.has(arr[j]))
unmap.set(arr[j], unmap.get(arr[j])+1);
else
unmap.set(arr[j],1);
sum += arr[j];
if (unmap.size == (j - i + 1)) {
result = Math.max(result, sum);
}
else {
break ;
}
}
}
return result;
}
let arr = [ 1, 2, 3, 3, 4, 5, 2, 1 ];
let ans = maxSumSubarray(arr, 8);
console.log(ans);
|
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach 1: Using Two Pointer Technique
To optimize the above approach the idea is to use the Two Pointer technique. Follow the steps below to solve the approach:
- Initialize two pointers i and j as 0 and 1 respectively to store the starting and ending index of the resultant subarray.
- Initialize a HashSet to store the array elements.
- Start from an empty subarray with i = 0 and j = 0 and traverse the array until any duplicate element is found and update the current sum to the maximum sum(say max_sum) if it is found to be greater than the current max_sum.
- If the duplicate element is found, increment j and update the variables until only unique elements are left in the current subarray from index j to i.
- Repeat the above steps for the rest of the array and keep updating the max_sum.
- Print the maximum sum obtained after completing the above steps.
Below is the implementation of the above approach:
C++
#include<bits/stdc++.h>
using namespace std;
int maxSumSubarray( int arr[], int n)
{
int i = 0, j = 1;
set< int > set;
set.insert(arr[0]);
int sum = arr[0];
int maxsum = sum;
while (i < n - 1 && j < n)
{
const bool is_in = set.find(arr[j]) !=
set.end();
if (!is_in)
{
sum = sum + arr[j];
maxsum = max(sum, maxsum);
set.insert(arr[j++]);
}
else
{
sum -= arr[i];
set.erase(arr[i++]);
}
}
return maxsum;
}
int main()
{
int arr[] = {1, 2, 3, 1, 5};
int ans = maxSumSubarray(arr, 5);
cout << (ans);
}
|
Java
import java.io.*;
import java.lang.Math;
import java.util.*;
public class GFG {
public static int
maxSumSubarray( int [] arr)
{
int i = 0 , j = 1 ;
HashSet<Integer> set
= new HashSet<Integer>();
set.add(arr[ 0 ]);
int sum = arr[ 0 ];
int maxsum = sum;
while (i < arr.length - 1
&& j < arr.length) {
if (!set.contains(arr[j])) {
sum = sum + arr[j];
maxsum = Math.max(sum,
maxsum);
set.add(arr[j++]);
}
else {
sum -= arr[i];
set.remove(arr[i++]);
}
}
return maxsum;
}
public static void
main(String[] args)
{
int arr[] = new int [] { 1 , 2 , 3 , 1 , 5 };
int ans = maxSumSubarray(arr);
System.out.println(ans);
}
}
|
Python3
def maxSumSubarray(arr):
i = 0
j = 1
set = {}
set [arr[ 0 ]] = 1
sum = arr[ 0 ]
maxsum = sum
while (i < len (arr) - 1 and
j < len (arr)):
if arr[j] not in set :
sum = sum + arr[j]
maxsum = max ( sum , maxsum)
set [arr[j]] = 1
j + = 1
else :
sum - = arr[i]
del set [arr[i]]
i + = 1
return maxsum
if __name__ = = '__main__' :
arr = [ 1 , 2 , 3 , 1 , 5 ]
ans = maxSumSubarray(arr)
print (ans)
|
C#
using System;
using System.Collections.Generic;
class GFG{
public static int maxSumSubarray( int [] arr)
{
int i = 0, j = 1;
HashSet< int > set =
new HashSet< int >();
set .Add(arr[0]);
int sum = arr[0];
int maxsum = sum;
while (i < arr.Length - 1 &&
j < arr.Length)
{
if (! set .Contains(arr[j]))
{
sum = sum + arr[j];
maxsum = Math.Max(sum,
maxsum);
set .Add(arr[j++]);
}
else
{
sum -= arr[i];
set .Remove(arr[i++]);
}
}
return maxsum;
}
public static void Main(String[] args)
{
int []arr = new int [] {1, 2,
3, 1, 5};
int ans = maxSumSubarray(arr);
Console.WriteLine(ans);
}
}
|
Javascript
<script>
function maxSumSubarray(arr, n)
{
var i = 0, j = 1;
var set = new Set();
set.add(arr[0]);
var sum = arr[0];
var maxsum = sum;
while (i < n - 1 && j < n)
{
var is_in = set.has(arr[j]);
if (!is_in)
{
sum = sum + arr[j];
maxsum = Math.max(sum, maxsum);
set.add(arr[j++]);
}
else
{
sum -= arr[i];
set. delete (arr[i++]);
}
}
return maxsum;
}
var arr = [ 1, 2, 3, 1, 5 ];
var ans = maxSumSubarray(arr, 5);
document.write(ans);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Efficient Approach 2: Using Prefix Sum
To optimize the above approach the idea is to use the Prefix Sum array. Follow the steps below to solve the approach:
- Create an array containing the sum of all elements before index i. This is called the prefix sum array.
- Create an hashset containing the index of last occurrence of an element.
- Initialize the resultant global maximum sum with 0.
- Initialize two pointers i and j at index 0 and traverse the array with the pointer i.
- If the current element has occurred before, reinitialize j with the maximum value between j and the last occurrence of the current element.
- The resultant global maximum sum = max(global maximum sum till now, prefixSum[i] – prefixSum[j] + current element) as the prefixSum[i] – prefixSum[j] will give us the sum between index i and j.
- Update the last occurrence of current element to index i+1.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maxSumUniqueSubarray( int * arr, int n)
{
vector< int > preSum(n + 1);
preSum[0] = 0;
for ( int i = 1; i <= n; i++)
preSum[i] = preSum[i - 1] + arr[i - 1];
vector< int > lastSeen(1e4+1, 0);
int res = 0;
int j = 0;
for ( int i = 0; i < n; i++)
{
int num = arr[i];
if (lastSeen[num] > 0)
{
j = max(j, lastSeen[num]);
}
res = max(res, preSum[i] + num - preSum[j]);
lastSeen[num] = i + 1;
}
return res;
}
int main()
{
int arr[] = {1, 2, 3, 1, 5};
int ans = maxSumUniqueSubarray(arr, 5);
cout << (ans);
}
|
Java
import java.io.*;
import java.lang.*;
class GFG {
static int maxSumUniqueSubarray( int [] arr, int n)
{
int [] preSum = new int [n+ 1 ];
preSum[ 0 ] = 0 ;
for ( int i = 1 ; i <= n; i++)
{
preSum[i] = preSum[i- 1 ]+arr[i- 1 ];
}
int [] lastSeen = new int [ 10001 ];
int res = 0 ;
int j = 0 ;
for ( int i = 0 ; i < n; i++)
{
int num = arr[i];
if (lastSeen[num] > 0 )
{
j = Math.max(j, lastSeen[num]);
}
res = Math.max(res, (preSum[i] + num - preSum[j]));
lastSeen[num] = i+ 1 ;
}
return res;
}
public static void main(String[] args)
{
int [] arr = { 1 , 2 , 3 , 1 , 5 };
int ans = maxSumUniqueSubarray(arr, 5 );
System.out.println(ans);
}
}
|
Python
def maxSumUniqueSubarray(arr, n):
preSum = [ 0 ] * (n + 1 )
preSum[ 0 ] = 0
for i in range ( 1 , n + 1 ):
preSum[i] = preSum[i - 1 ] + arr[i - 1 ]
lastSeen = [ 0 ] * ( 10 * * 4 + 1 )
res = 0
j = 0
for i in range (n):
num = arr[i]
if lastSeen[num] > 0 :
j = max (j, lastSeen[num])
res = max (res, preSum[i] + num - preSum[j])
lastSeen[num] = i + 1
return res
arr = [ 1 , 2 , 3 , 1 , 5 ]
ans = maxSumUniqueSubarray(arr, 5 )
print (ans)
|
C#
using System;
using System.Collections.Generic;
namespace ConsoleApp1 {
class Program {
static int maxSumUniqueSubarray( int [] arr, int n)
{
var preSum = new int [n + 1];
preSum[0] = 0;
for ( int i = 1; i <= n; i++)
preSum[i] = preSum[i - 1] + arr[i - 1];
var lastSeen = new int [10000 + 1];
int res = 0;
int j = 0;
for ( int i = 0; i < n; i++) {
int num = arr[i];
if (lastSeen[num] > 0) {
j = Math.Max(j, lastSeen[num]);
}
res = Math.Max(res,
preSum[i] + num - preSum[j]);
lastSeen[num] = i + 1;
}
return res;
}
static void Main( string [] args)
{
int [] arr = { 1, 2, 3, 1, 5 };
int ans = maxSumUniqueSubarray(arr, 5);
Console.WriteLine(ans);
}
}
}
|
Javascript
const maxSumUniqueSubarray = (arr, n) => {
let preSum = [], lastSeen = [];
preSum[0] = 0;
for (let i = 1; i <= n; i++)
preSum[i] = preSum[i - 1] + arr[i - 1];
lastSeen = Array(10000 + 1).fill(0);
let res = 0;
let j = 0;
for (let i = 0; i < n; i++) {
let num = arr[i];
if (lastSeen[num] > 0)
j = Math.max(j, lastSeen[num]);
res = Math.max(res, preSum[i] + num - preSum[j]);
lastSeen[num] = i + 1;
}
return res;
}
let arr = [1, 2, 3, 1, 5];
let ans = maxSumUniqueSubarray(arr, 5);
console.log(ans);
|
Time Complexity: O(N)
Auxiliary Space: O(MAX(N,max_element))
Last Updated :
27 Jan, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...