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 = 15Input: 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); |
15
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> |
11
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 |
11
Time Complexity: O(N)
Auxiliary Space: O(MAX(N,max_element))
Please Login to comment...