Largest Sum Contiguous Subarray having unique elements
Last Updated :
27 Jan, 2023
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++
// C++ program for
// the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to calculate required
// maximum subarray sum
int maxSumSubarray(int arr[], int n)
{
int result = 0;
for (int i = 0; i < n; i++) {
int sum = 0;
// For keep track of duplicate elements in current
// subarray
unordered_map<int, int> unmap;
for (int j = i; j < n; j++) {
unmap[arr[j]]++;
sum += arr[j];
// Check if current subarray contains any
// duplicate
if (unmap.size() == (j - i + 1)) {
result = max(result, sum);
}
else {
break;
}
}
}
return result;
}
// Driver Code
int main()
{
// Given array arr[]
int arr[] = { 1, 2, 3, 3, 4, 5, 2, 1 };
// Function Call
int ans = maxSumSubarray(arr, 8);
// Print the maximum sum
cout << (ans);
}
Java
/*package whatever //do not write package name here */
import java.io.*;
import java.util.*;
class GFG
{
// Function to calculate required
// maximum subarray sum
public static int maxSumSubarray(int arr[], int n)
{
int result = 0;
for (int i = 0; i < n; i++) {
int sum = 0;
// For keep track of duplicate elements in current
// subarray
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];
// Check if current subarray contains any
// duplicate
if (hm.size() == (j - i + 1)) {
result = Math.max(result, sum);
}
else {
break;
}
}
}
return result;
}
public static void main (String[] args)
{
// Given array arr[]
int arr[] = { 1, 2, 3, 3, 4, 5, 2, 1 };
// Function Call
int ans = maxSumSubarray(arr, 8);
// Print the maximum sum
System.out.println(ans);
}
}
// This code is contributed by sourabhdalal0001.
Python3
from collections import defaultdict
#Function to calculate required
#maximum subarray sum
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
# Given array arr[]
arr = [1, 2, 3, 3, 4, 5, 2, 1]
# Function Call
ans = maxSumSubarray(arr, 8)
# Print the maximum sum
print(ans)
C#
using System;
using System.Collections.Generic;
class GFG {
// Function to calculate required
// maximum subarray sum
public static int maxSumSubarray(int[] arr, int n)
{
int result = 0;
for (int i = 0; i < n; i++) {
int sum = 0;
// For keep track of duplicate elements in
// current subarray
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];
// Check if current subarray contains any
// duplicate
if (hm.Count == (j - i + 1)) {
result = Math.Max(result, sum);
}
else {
break;
}
}
}
return result;
}
public static void Main(string[] args)
{
// Given array arr[]
int[] arr = { 1, 2, 3, 3, 4, 5, 2, 1 };
// Function Call
int ans = maxSumSubarray(arr, 8);
// Print the maximum sum
Console.WriteLine(ans);
}
}
JavaScript
// Javascript program for the above approach
// Function to calculate required
// maximum subarray sum
function maxSumSubarray( arr, n)
{
let result = 0;
for (let i = 0; i < n; i++) {
let sum = 0;
// For keep track of duplicate elements in current
// subarray
//unordered_map<int, int> unmap;
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];
// Check if current subarray contains any
// duplicate
if (unmap.size == (j - i + 1)) {
result = Math.max(result, sum);
}
else {
break;
}
}
}
return result;
}
// Driver Code
// Given array arr[]
let arr = [ 1, 2, 3, 3, 4, 5, 2, 1 ];
// Function Call
let ans = maxSumSubarray(arr, 8);
// Print the maximum sum
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++
// C++ program for
// the above approach
#include<bits/stdc++.h>
using namespace std;
// Function to calculate required
// maximum subarray sum
int maxSumSubarray(int arr[], int n)
{
// Initialize two pointers
int i = 0, j = 1;
// Stores the unique elements
set<int> set;
// Insert the first element
set.insert(arr[0]);
// Current max sum
int sum = arr[0];
// Global maximum sum
int maxsum = sum;
while (i < n - 1 && j < n)
{
// Update sum & increment j
// auto pos = s.find(3);
const bool is_in = set.find(arr[j]) !=
set.end();
if (!is_in)
{
sum = sum + arr[j];
maxsum = max(sum, maxsum);
// Add the current element
set.insert(arr[j++]);
}
// Update sum and increment i
// and remove arr[i] from set
else
{
sum -= arr[i];
// Remove the element
// from start position
set.erase(arr[i++]);
}
}
// Return the maximum sum
return maxsum;
}
// Driver Code
int main()
{
// Given array arr[]
int arr[] = {1, 2, 3, 1, 5};
// Function Call
int ans = maxSumSubarray(arr, 5);
// Print the maximum sum
cout << (ans);
}
// This code is contributed by gauravrajput1
Java
// Java program for the above approach
import java.io.*;
import java.lang.Math;
import java.util.*;
public class GFG {
// Function to calculate required
// maximum subarray sum
public static int
maxSumSubarray(int[] arr)
{
// Initialize two pointers
int i = 0, j = 1;
// Stores the unique elements
HashSet<Integer> set
= new HashSet<Integer>();
// Insert the first element
set.add(arr[0]);
// Current max sum
int sum = arr[0];
// Global maximum sum
int maxsum = sum;
while (i < arr.length - 1
&& j < arr.length) {
// Update sum & increment j
if (!set.contains(arr[j])) {
sum = sum + arr[j];
maxsum = Math.max(sum,
maxsum);
// Add the current element
set.add(arr[j++]);
}
// Update sum and increment i
// and remove arr[i] from set
else {
sum -= arr[i];
// Remove the element
// from start position
set.remove(arr[i++]);
}
}
// Return the maximum sum
return maxsum;
}
// Driver Code
public static void
main(String[] args)
{
// Given array arr[]
int arr[] = new int[] { 1, 2, 3, 1, 5 };
// Function Call
int ans = maxSumSubarray(arr);
// Print the maximum sum
System.out.println(ans);
}
}
Python3
# Python3 program for the above approach
# Function to calculate required
# maximum subarray sum
def maxSumSubarray(arr):
# Initialize two pointers
i = 0
j = 1
# Stores the unique elements
set = {}
# Insert the first element
set[arr[0]] = 1
# Current max sum
sum = arr[0]
# Global maximum sum
maxsum = sum
while (i < len(arr) - 1 and
j < len(arr)):
# Update sum & increment j
if arr[j] not in set:
sum = sum + arr[j]
maxsum = max(sum, maxsum)
# Add the current element
set[arr[j]] = 1
j += 1
# Update sum and increment i
# and remove arr[i] from set
else:
sum -= arr[i]
# Remove the element
# from start position
del set[arr[i]]
i += 1
# Return the maximum sum
return maxsum
# Driver Code
if __name__ == '__main__':
# Given array arr[]
arr = [ 1, 2, 3, 1, 5 ]
# Function call
ans = maxSumSubarray(arr)
# Print the maximum sum
print(ans)
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to calculate
// required maximum subarray sum
public static int maxSumSubarray(int[] arr)
{
// Initialize two pointers
int i = 0, j = 1;
// Stores the unique elements
HashSet<int> set =
new HashSet<int>();
// Insert the first element
set.Add(arr[0]);
// Current max sum
int sum = arr[0];
// Global maximum sum
int maxsum = sum;
while (i < arr.Length - 1 &&
j < arr.Length)
{
// Update sum & increment j
if (!set.Contains(arr[j]))
{
sum = sum + arr[j];
maxsum = Math.Max(sum,
maxsum);
// Add the current element
set.Add(arr[j++]);
}
// Update sum and increment i
// and remove arr[i] from set
else
{
sum -= arr[i];
// Remove the element
// from start position
set.Remove(arr[i++]);
}
}
// Return the maximum sum
return maxsum;
}
// Driver Code
public static void Main(String[] args)
{
// Given array []arr
int []arr = new int[] {1, 2,
3, 1, 5};
// Function Call
int ans = maxSumSubarray(arr);
// Print the maximum sum
Console.WriteLine(ans);
}
}
// This code is contributed by shikhasingrajput
JavaScript
<script>
// Javascript program for
// the above approach
// Function to calculate required
// maximum subarray sum
function maxSumSubarray(arr, n)
{
// Initialize two pointers
var i = 0, j = 1;
// Stores the unique elements
var set = new Set();
// Insert the first element
set.add(arr[0]);
// Current max sum
var sum = arr[0];
// Global maximum sum
var maxsum = sum;
while (i < n - 1 && j < n)
{
// Update sum & increment j
// auto pos = s.find(3);
var is_in = set.has(arr[j]);
if (!is_in)
{
sum = sum + arr[j];
maxsum = Math.max(sum, maxsum);
// Add the current element
set.add(arr[j++]);
}
// Update sum and increment i
// and remove arr[i] from set
else
{
sum -= arr[i];
// Remove the element
// from start position
set.delete(arr[i++]);
}
}
// Return the maximum sum
return maxsum;
}
// Driver Code
// Given array arr[]
var arr = [ 1, 2, 3, 1, 5 ];
// Function Call
var ans = maxSumSubarray(arr, 5);
// Print the maximum sum
document.write(ans);
// This code is contributed by rutvik_56
</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)
{
// Create the prefix sum array
vector<int> preSum(n + 1);
preSum[0] = 0;
for (int i = 1; i <= n; i++)
preSum[i] = preSum[i - 1] + arr[i - 1];
// Create an hashset containing the index of last occurrence of an element
vector<int> lastSeen(1e4+1, 0);
// Initialize the resultant global maximum sum with 0.
int res = 0;
// Initialize two pointers i and j at index 0
// Traverse the array with the pointer i.
int j = 0;
for (int i = 0; i < n; i++)
{
int num = arr[i];
// If the current element has occurred before,
// reinitialize j with the maximum value between j and
// the last occurrence of the current element.
if (lastSeen[num] > 0)
{
j = max(j, lastSeen[num]);
}
// Update the resultant global maximum sum
res = max(res, preSum[i] + num - preSum[j]);
// Update the last occurrence of current element to index i+1.
lastSeen[num] = i + 1;
}
return res;
}
// Driver Code
int main()
{
// Given array arr[]
int arr[] = {1, 2, 3, 1, 5};
// Function Call
int ans = maxSumUniqueSubarray(arr, 5);
// Print the maximum sum
cout << (ans);
}
// This code is contributed by akashkumarsen4
Java
import java.io.*;
import java.lang.*;
class GFG {
static int maxSumUniqueSubarray(int[] arr, int n)
{
int[] preSum = new int[n+1];
//ArrayList<Integer> preSum = new ArrayList<Integer>(n+1);
preSum[0] = 0;
for (int i = 1; i <= n; i++)
{
preSum[i] = preSum[i-1]+arr[i-1];
}
// Create an hashset containing the index of last occurrence of an element
int[] lastSeen = new int[10001];
// Initialize the resultant global maximum sum with 0.
int res = 0;
// Initialize two pointers i and j at index 0
// Traverse the array with the pointer i.
int j = 0;
for (int i = 0; i < n; i++)
{
int num = arr[i];
// If the current element has occurred before,
// reinitialize j with the maximum value between j and
// the last occurrence of the current element.
if (lastSeen[num] > 0)
{
j = Math.max(j, lastSeen[num]);
}
// Update the resultant global maximum sum
res = Math.max(res, (preSum[i] + num - preSum[j]));
// Update the last occurrence of current element to index i+1.
lastSeen[num] = i+1;
}
return res;
}
public static void main(String[] args)
{
// Given array arr[]
int[] arr = {1, 2, 3, 1, 5};
// Function Call
int ans = maxSumUniqueSubarray(arr, 5);
// Print the maximum sum
System.out.println(ans);
}
}
// This code is contributed by aditya942003patil
Python
def maxSumUniqueSubarray(arr, n):
# Create the prefix sum array
preSum = [0] * (n + 1)
preSum[0] = 0
for i in range(1, n + 1):
preSum[i] = preSum[i - 1] + arr[i - 1]
# Create an hashset containing the index of last occurrence of an element
lastSeen = [0] * (10 ** 4 + 1)
# Initialize the resultant global maximum sum with 0.
res = 0
# Initialize two pointers i and j at index 0
# Traverse the array with the pointer i.
j = 0
for i in range(n):
num = arr[i]
# If the current element has occurred before,
# reinitialize j with the maximum value between j and
# the last occurrence of the current element.
if lastSeen[num] > 0:
j = max(j, lastSeen[num])
# Update the resultant global maximum sum
res = max(res, preSum[i] + num - preSum[j])
# Update the last occurrence of current element to index i+1.
lastSeen[num] = i + 1
return res
# Given array arr[]
arr = [1, 2, 3, 1, 5]
# Function Call
ans = maxSumUniqueSubarray(arr, 5)
# Print the maximum sum
print(ans)
C#
using System;
using System.Collections.Generic;
namespace ConsoleApp1 {
class Program {
static int maxSumUniqueSubarray(int[] arr, int n)
{
// Create the prefix sum array
var preSum = new int[n + 1];
preSum[0] = 0;
for (int i = 1; i <= n; i++)
preSum[i] = preSum[i - 1] + arr[i - 1];
// Create an hashset containing the index of last
// occurrence of an element
var lastSeen = new int[10000 + 1];
// Initialize the resultant global maximum sum with
// 0.
int res = 0;
// Initialize two pointers i and j at index 0
// Traverse the array with the pointer i.
int j = 0;
for (int i = 0; i < n; i++) {
int num = arr[i];
// If the current element has occurred before,
// reinitialize j with the maximum value between
// j and the last occurrence of the current
// element.
if (lastSeen[num] > 0) {
j = Math.Max(j, lastSeen[num]);
}
// Update the resultant global maximum sum
res = Math.Max(res,
preSum[i] + num - preSum[j]);
// Update the last occurrence of current element
// to index i+1.
lastSeen[num] = i + 1;
}
return res;
}
static void Main(string[] args)
{
// Given array arr[]
int[] arr = { 1, 2, 3, 1, 5 };
// Function Call
int ans = maxSumUniqueSubarray(arr, 5);
// Print the maximum sum
Console.WriteLine(ans);
}
}
}
// This code is contributed by aadityamaharshi21.
JavaScript
// Javascript program for above approach
const maxSumUniqueSubarray = (arr, n) => {
// Create the prefix sum array
let preSum = [], lastSeen = [];
preSum[0] = 0;
for (let i = 1; i <= n; i++)
preSum[i] = preSum[i - 1] + arr[i - 1];
// Create an hashset containing the index of last occurrence of an element
lastSeen = Array(10000 + 1).fill(0);
// Initialize the resultant global maximum sum with 0.
let res = 0;
// Initialize two pointers i and j at index 0
// Traverse the array with the pointer i.
let j = 0;
for (let i = 0; i < n; i++) {
let num = arr[i];
// If the current element has occurred before,
// reinitialize j with the maximum value between j and
// the last occurrence of the current element.
if (lastSeen[num] > 0)
j = Math.max(j, lastSeen[num]);
// Update the resultant global maximum sum
res = Math.max(res, preSum[i] + num - preSum[j]);
// Update the last occurrence of current element to index i+1.
lastSeen[num] = i + 1;
}
return res;
}
// Function Call
let arr = [1, 2, 3, 1, 5];
let ans = maxSumUniqueSubarray(arr, 5);
// Print the maximum sum
console.log(ans);
// this is contributed by adityamaharshi21
Time Complexity: O(N)
Auxiliary Space: O(MAX(N,max_element))
Similar Reads
Largest sum contiguous increasing subarray Given an array of n positive distinct integers. The problem is to find the largest sum of contiguous increasing subarray in O(n) time complexity. Examples : Input : arr[] = {2, 1, 4, 7, 3, 6}Output : 12Contiguous Increasing subarray {1, 4, 7} = 12Input : arr[] = {38, 7, 8, 10, 12}Output : 38Recommen
15 min read
Length of the largest subarray with contiguous elements | Set 2 Given an array of integers, find length of the longest subarray which contains numbers that can be arranged in a continuous sequence. In the previous post, we have discussed a solution that assumes that elements in given array are distinct. Here we discuss a solution that works even if the input arr
7 min read
Length of the largest subarray with contiguous elements | Set 1 Given an array of distinct integers, find length of the longest subarray which contains numbers that can be arranged in a continuous sequence. Examples: Input: arr[] = {10, 12, 11}; Output: Length of the longest contiguous subarray is 3 Input: arr[] = {14, 12, 11, 20}; Output: Length of the longest
7 min read
Longest Subarray consisting of unique elements from an Array Given an array arr[] consisting of N integers, the task is to find the largest subarray consisting of unique elements only. Examples: Input: arr[] = {1, 2, 3, 4, 5, 1, 2, 3} Output: 5 Explanation: One possible subarray is {1, 2, 3, 4, 5}. Input: arr[]={1, 2, 4, 4, 5, 6, 7, 8, 3, 4, 5, 3, 3, 4, 5, 6,
5 min read
Largest sum subarray of size K containing consecutive elements Given an array arr[] consisting of N positive integers and a positive integer K, the task is to find the maximum sum of the subarray of size K such that it contains K consecutive elements in any combination. Examples: Input: arr[] = {10, 12, 9, 8, 10, 15, 1, 3, 2}, K = 3Output: 27Explanation:The sub
8 min read