Maximum sum subarray such that start and end values are same - GeeksforGeeks

20 Dec, 2021
Given an array of N positive numbers, the task is to find a contiguous subarray (L-R) such that a[L]=a[R] and sum of a[L] + a[L+1] +...+ a[R] is maximum.Examples:  
Input: arr[] = {1, 3, 2, 2, 3}
Output: 10
Subarray [3, 2, 2, 3] starts and ends with 3 and has sum = 10

Input: arr[] = {1, 3, 2, 2, 3}
Output: 10
 
Approach: For every element in the array, let’s find 2 values: First (Leftmost) occurrence in the array and Last (Rightmost) occurrence in the array. Since all numbers are positive, increasing the number of terms can only increase the sum. Hence for every number in the array, we find the sum between it’s leftmost and rightmost occurrence, which can be done quickly using prefix sums. We can keep track of the maximum value found so far and print it in the end.Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
// C++ implementation of the above approach#include <bits/stdc++.h>using namespace std; // Function to find the maximum sumint maxValue(int a[], int n){    unordered_map<int, int> first, last;    int pr[n];     for (int i = 0; i < n; i++) {         // Build prefix sum array        if (i)            pr[i] = pr[i - 1] + a[i];        else            pr[i] = a[i];        // If the value hasn't been encountered before,        // It is the first occurrence        if (first[a[i]] == 0)            first[a[i]] = i + 1;         // Keep updating the last occurrence        last[a[i]] = i + 1;    }     int ans = 0;     // Find the maximum sum with same first and last value    for (int i = 0; i < n; i++) {        int start = first[a[i]];        int end = last[a[i]];        if (start == 1) ans = max(ans, pr[end - 1]);        else ans = max(ans, pr[end - 1] - pr[start - 2]);    }    return ans;} // Driver Codeint main(){    int arr[] = {1,2,31,2,1};    int n = sizeof(arr) / sizeof(arr[0]);     cout << maxValue(arr, n);     return 0;}
import java.util.HashMap; class GFG {    static int maxValue(int[] a, int n)    {        HashMap<Integer, Integer> first = new HashMap<>();        HashMap<Integer, Integer> last = new HashMap<>();         int[] prefix = new int[n];         for (int i = 0; i < n; i++) {             // Build prefix sum array            if (i != 0)                prefix[i] = prefix[i - 1] + a[i];            else                prefix[i] = a[i];            // If the value hasn't been encountered before,            // It is the first occurrence            if (!first.containsKey(a[i]))                first.put(a[i], i);             // Keep updating the last occurrence            last.put(a[i], i);        }         int ans = -1;         // Find the maximum sum with same first and last        // value        for (int i = 0; i < n; i++) {            int start = first.get(a[i]);            int end = last.get(a[i]);            int sum = 0;            if(start == 0)                sum = prefix[end];            else                sum = prefix[end] - prefix[start - 1];            if(sum > ans)                ans = sum;        }         return ans;    }     // Driver Code    public static void main(String args[])    {        int[] arr = { 1, 3, 5, 2, 4, 18, 2, 3 };        int n = arr.length;        System.out.print(maxValue(arr, n));    }}
# Python3 implementation of the above approachfrom collections import defaultdict # Function to find the maximum sum  def maxValue(a, n):     first = defaultdict(lambda: 0)    last = defaultdict(lambda: 0)     pr = [None] * n    pr[0] = a[0]    first[a[0]] = 1    last[a[0]] = 1    for i in range(1, n):         # Build prefix sum array        pr[i] = pr[i - 1] + a[i]         # If the value hasn't been encountered before,        # It is the first occurrence        if first[a[i]] == 0:            first[a[i]] = i+1         # Keep updating the last occurrence        last[a[i]] = i+1     ans = 0     # Find the maximum sum with same first and last value    for i in range(0, n):        start = first[a[i]]        end = last[a[i]]        if start != 1:            ans = max(ans, pr[end-1] - pr[start - 2])     return ans  # Driver Codeif __name__ == "__main__":     arr = [1, 3, 5, 2, 4, 18, 2, 3]    n = len(arr)     print(maxValue(arr, n)) # This code is contributed by Rituraj Jain
// C# implementation of the above approachusing System;using System.Collections.Generic; class GFG {     // Function to find the maximum sum    static int maxValue(int[] a, int n)    {        Dictionary<int, int> first            = new Dictionary<int, int>();        Dictionary<int, int> last            = new Dictionary<int, int>();         for (int i = 0; i < n; i++) {            first[a[i]] = 0;            last[a[i]] = 0;        }         int[] pr = new int[n];        pr[0] = a[0];        first[a[0]] = 1;        last[a[0]] = 1;        for (int i = 1; i < n; i++) {             // Build prefix sum array            pr[i] = pr[i - 1] + a[i];             // If the value hasn't been encountered before,            // It is the first occurrence            if (first[a[i]] == 0)                first[a[i]] = i + 1;             // Keep updating the last occurrence            last[a[i]] = i + 1;        }         int ans = 0;         // Find the maximum sum with        // same first and last value        for (int i = 0; i < n; i++) {            int start = first[a[i]];            int end = last[a[i]];            if (start != 1)                ans = Math.Max(ans,                               pr[end - 1] - pr[start - 2]);        }        return ans;    }     // Driver Code    static void Main()    {        int[] arr = { 1, 3, 5, 2, 4, 18, 2, 3 };        int n = arr.Length;        Console.Write(maxValue(arr, n));    }} // This code is contributed by mohit kumar
<script> // JavaScript implementation of the above approach // Function to find the maximum sumfunction maxValue(a,n){    let first = new Map();        let last = new Map();        for (let i = 0; i < n; i++) {            first.set(a[i], 0);            last.set(a[i], 0);        }           let pr = new Array(n);        pr[0] = a[0];        first[a[0]] = 0;        last[a[0]] = 0;        for (let i = 1; i < n; i++) {               // Build prefix sum array            pr[i] = pr[i - 1] + a[i];               // If the value hasn't been encountered before,            // It is the first occurrence            if (parseInt((first.get(a[i]))) == 0)                first.set(a[i], i+1);               // Keep updating the last occurrence            last.set(a[i], i+1);        }           let ans = 0;           // Find the maximum sum with same first and last value        for (let i = 0; i < n; i++) {            let start = parseInt(first.get(a[i]));            let end = parseInt(last.get(a[i]));            if (start != 1)                ans = Math.max(ans, pr[end-1] - pr[start - 2]);        }           return ans;} // Driver Codelet arr=[1, 3, 5, 2, 4, 18, 2, 3 ];let n = arr.length;document.write(maxValue(arr, n));          // This code is contributed by patel2127 </script>
37
Time Complexity: O(N) 
rituraj_jain
rachana soma
mohit kumar 29
patel2127
anujpanchal2001
yashgupta1249
cpp-unordered_map
prefix-sum
subarray
subarray-sum
Algorithms
Arrays
prefix-sum
Arrays
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
SDE SHEET - A Complete Guide for SDE Preparation
DSA Sheet by Love Babbar
How to write a Pseudo Code?
Understanding Time Complexity with Simple Examples
Introduction to Algorithms
Arrays in Java
Arrays in C/C++
Maximum and minimum of an array using minimum number of comparisons
Write a program to reverse an array or string
Program for array rotation