📜  最大和子数组,使得开始和结束值相同

📅  最后修改于: 2021-04-27 22:23:47             🧑  作者: Mango

给定一个由N个正数组成的数组,任务是要找到一个连续的子数组(LR),使得a [L] = a [R]a [L] + a [L + 1] +…+ a [R ]为最大。

例子:

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

方法:对于数组中的每个元素,让我们找到2个值:数组中的第一个(最左)和数组中的最后一个(最右)。由于所有数字均为正数,因此增加项数只会增加总和。因此,对于数组中的每个数字,我们都找到它最左边和最右边出现之间的总和,可以使用前缀总和快速完成。我们可以跟踪到目前为止找到的最大值并最终打印出来。

下面是上述方法的实现:

C++
// C++ implementation of the above approach
#include 
using namespace std;
  
// Function to find the maximum sum
int maxValue(int a[], int n)
{
    unordered_map first, last;
    int pr[n];
    pr[0] = a[0];
  
    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;
  
        // Keep updating the last occurrence
        last[a[i]] = i;
    }
  
    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]];
        ans = max(ans, pr[end] - pr[start - 1]);
    }
    return ans;
}
  
// Driver Code
int main()
{
    int arr[] = { 1, 3, 5, 2, 4, 18, 2, 3 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    cout << maxValue(arr, n);
  
    return 0;
}


Java
// Java implementation of the above approach
import java.io.*;
import java.util.*;
  
class GFG {
  
    // Function to find the maximum sum
    static int maxValue(int a[], int n)
    {
        HashMap first = new HashMap<>();
        HashMap last = new HashMap<>();
        for (int i = 0; i < n; i++) {
            first.put(a[i], 0);
            last.put(a[i], 0);
        }
  
        int[] pr = new int[n];
        pr[0] = a[0];
  
        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 (Integer.parseInt(String.valueOf(first.get(a[i]))) == 0)
                first.put(a[i], i);
  
            // Keep updating the last occurrence
            last.put(a[i], i);
        }
  
        int ans = 0;
  
        // Find the maximum sum with same first and last value
        for (int i = 0; i < n; i++) {
            int start = Integer.parseInt(String.valueOf(first.get(a[i])));
            int end = Integer.parseInt(String.valueOf(last.get(a[i])));
            if (start != 0)
                ans = Math.max(ans, pr[end] - pr[start - 1]);
        }
  
        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));
    }
}
  
// This code is contributed by rachana soma


Python3
# Python3 implementation of the above approach 
from 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] 
    
    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 
    
        # Keep updating the last occurrence 
        last[a[i]] = i 
       
    
    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]] 
        ans = max(ans, pr[end] - pr[start - 1]) 
       
    return ans 
   
    
# Driver Code 
if __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#
// C# implementation of the above approach
using System;
using System.Collections.Generic;
  
class GFG 
{
  
    // Function to find the maximum sum
    static int maxValue(int []a, int n)
    {
        Dictionary first = new Dictionary();
        Dictionary last = new Dictionary();
          
        for (int i = 0; i < n; i++) 
        {
            first[a[i]] = 0;
            last[a[i]] = 0;
        }
  
        int[] pr = new int[n];
        pr[0] = a[0];
  
        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;
  
            // Keep updating the last occurrence
            last[a[i]] = i;
        }
  
        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 != 0)
                ans = Math.Max(ans, pr[end] - pr[start - 1]);
        }
        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


输出:
37

时间复杂度: O(N)