Subarreglo contiguo de suma más grande que tiene elementos únicos

Dado un arreglo arr[] de N enteros positivos, la tarea es encontrar el subarreglo que tiene la suma máxima entre todos los subarreglos que tienen elementos únicos e imprimir su suma. 

Input arr[] = {1, 2, 3, 3, 4, 5, 2, 1}
Output: 15
Explicación:
El subarreglo que tiene la suma máxima con elementos distintos es {3, 4, 5, 2, 1}.
Por lo tanto, la suma es = 3 + 4 + 5 + 2 + 1 = 15

Entrada: array[] = {1, 2, 3, 1, 5}
Salida: 11
Explicación:
El subarreglo que tiene la suma máxima con elementos distintos es {2, 3, 1, 5}.
Por lo tanto, la suma es = 2 + 3 + 1 + 5 = 11.

Enfoque ingenuo: el enfoque más simple para resolver el problema es generar todos los subarreglos posibles y, para cada subarreglo, verificar si todos sus elementos son únicos o no. Encuentra la suma máxima entre dichos subarreglos e imprímelo. 

Complejidad temporal: O(N 3 )
Espacio auxiliar: O(N) 

Enfoque eficiente 1: Uso de la técnica de dos punteros 

Para optimizar el enfoque anterior, la idea es utilizar la técnica Two Pointer . Siga los pasos a continuación para resolver el enfoque: 

  1. Inicialice dos punteros i y j como 0 y 1 respectivamente para almacenar el índice inicial y final del subarreglo resultante.
  2. Inicialice un HashSet para almacenar los elementos de la array.
  3. Comience desde un subarreglo vacío con i = 0 y j = 0 y recorra el arreglo hasta que se encuentre cualquier elemento duplicado y actualice la suma actual a la suma máxima (digamos max_sum ) si se encuentra que es mayor que el max_sum actual .
  4. Si se encuentra el elemento duplicado, incremente j y actualice las variables hasta que solo queden elementos únicos en el subarreglo actual desde el índice j hasta i .
  5. Repita los pasos anteriores para el resto de la array y siga actualizando max_sum .
  6. Imprime la suma máxima obtenida después de completar los pasos anteriores.

A continuación se muestra la implementación del enfoque anterior: 

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>
Producción

11

Complejidad temporal: O(N)
Espacio auxiliar: O(N)

Enfoque eficiente 2: uso de la suma de prefijos

Para optimizar el enfoque anterior, la idea es utilizar la array Prefix Sum . Siga los pasos a continuación para resolver el enfoque: 

  1. Cree una array que contenga la suma de todos los elementos antes del índice i. Esto se llama array de suma de prefijos.
  2. Cree un hashset que contenga el índice de la última aparición de un elemento.
  3. Inicialice la suma máxima global resultante con 0.
  4. Inicialice dos punteros i y j en el índice 0 y recorra la array con el puntero i.
  5. Si el elemento actual se ha producido antes, reinicialice j con el valor máximo entre j y la última aparición del elemento actual.
  6. La suma máxima global resultante = max(suma máxima global hasta ahora, prefixSum[i] – prefixSum[j] + elemento actual) como prefixSum[i] – prefixSum[j] nos dará la suma entre el índice i y j.
  7. Actualice la última aparición del elemento actual al índice i+1.

A continuación se muestra la implementación del enfoque anterior: 

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
Producción

11

Complejidad de tiempo: O(N)
Espacio auxiliar: O(MAX(N,max_element))

Publicación traducida automáticamente

Artículo escrito por abhinaygupta98 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *