Subarreglo de suma máxima eliminando como máximo un elemento

Dada una array, necesitamos encontrar el subarreglo de suma máxima, también se permite eliminar un elemento para obtener la suma máxima.

Ejemplos: 

Input  : arr[] = {1, 2, 3, -4, 5}
Output : 11
Explanation : We can get maximum sum subarray by
removing -4.

Input  : arr[] = [-2, -3, 4, -1, -2, 1, 5, -3]
Output : 9
Explanation : We can get maximum sum subarray by
removing -2 as, [4, -1, 1, 5] summing 9, which is 
the maximum achievable sum.

Si no se aplica la condición de eliminación de elementos, podemos resolver este problema usando el algoritmo de Kadane, pero aquí también se puede eliminar un elemento para aumentar la suma máxima. Esta condición se puede manejar usando dos arrays, array hacia adelante y hacia atrás, estas arrays almacenan la suma máxima actual del subarreglo desde el inicio hasta el i-ésimo índice, y desde el i-ésimo índice hasta el final, respectivamente. 

En el siguiente código, se escriben dos bucles, el primero almacena la suma de corriente máxima en dirección hacia adelante en fw[] y el otro bucle almacena lo mismo en dirección hacia atrás en bw[]. Obtener el máximo actual y la actualización es lo mismo que el algoritmo de Kadane. 

Ahora, cuando se crean ambos arreglos, podemos usarlos para las condiciones de eliminación de un elemento de la siguiente manera, en cada índice i, la suma máxima del subarreglo después de ignorar el i-ésimo elemento será fw[i-1] + bw[i+1] así que bucle para todos los valores i posibles y elegimos el máximo entre ellos. 

La complejidad temporal total y la complejidad espacial de la solución es O(N) 

Implementación:

C++

// C++ program to get maximum sum subarray removing
// at-most one element
#include <bits/stdc++.h>
using namespace std;
 
// Method returns maximum sum of all subarray where
// removing one element is also allowed
int maxSumSubarrayRemovingOneEle(int arr[], int n)
{
    // Maximum sum subarrays in forward and backward
    // directions
    int fw[n], bw[n];
 
    // Initialize current max and max so far.
    int cur_max = arr[0], max_so_far = arr[0];
 
    // calculating maximum sum subarrays in forward
    // direction
    fw[0] = arr[0];
    for (int i = 1; i < n; i++)
    {
        cur_max = max(arr[i], cur_max + arr[i]);
        max_so_far = max(max_so_far, cur_max);
 
        // storing current maximum till ith, in
        // forward array
        fw[i] = cur_max;
    }
 
    // calculating maximum sum subarrays in backward
    // direction
    cur_max = max_so_far = bw[n-1] = arr[n-1];
    for (int i = n-2; i >= 0; i--)
    {
        cur_max = max(arr[i], cur_max + arr[i]);
        max_so_far = max(max_so_far, cur_max);
 
        // storing current maximum from ith, in
        // backward array
        bw[i] = cur_max;
    }
 
    /* Initializing final ans by max_so_far so that,
        case when no element is removed to get max sum
        subarray is also handled */
    int fans = max_so_far;
 
    // choosing maximum ignoring ith element
    for (int i = 1; i < n - 1; i++)
        fans = max(fans,max(0, fw[i - 1]) +max(0, bw[i + 1]));
  // In this condition we are checking when removing the ith element
  // so checking the max(0,left)+max(0,right), because maybe
  // left<0 || right<0 so it wont contribute to the answer
        if(fans==0){
          // if no positive element in array so return max_element
            return *max_element(arr,arr+n);
        }
    return fans;
 
}
 
// Driver code to test above methods
int main()
{
    int arr[] = {-2, -3, 4, -1, -2, 1, 5, -3};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << maxSumSubarrayRemovingOneEle(arr, n);
    return 0;
}

Java

// Java program to get maximum sum subarray
// removing at-most one element
class GFG {
     
    // Method returns maximum sum of all subarray where
    // removing one element is also allowed
    static int maxSumSubarrayRemovingOneEle(int arr[],
                                                 int n)
    {
         
        // Maximum sum subarrays in forward and
        // backward directions
        int fw[] = new int[n];
        int bw[] = new int[n];
 
        // Initialize current max and max so far.
        int cur_max = arr[0], max_so_far = arr[0];
 
        // calculating maximum sum subarrays in forward
        // direction
        fw[0] = arr[0];
 
        for (int i = 1; i < n; i++) {
 
            cur_max = Math.max(arr[i], cur_max + arr[i]);
            max_so_far = Math.max(max_so_far, cur_max);
 
            // storing current maximum till ith, in
            // forward array
            fw[i] = cur_max;
        }
 
        // calculating maximum sum subarrays in backward
        // direction
        cur_max = max_so_far = bw[n - 1] = arr[n - 1];
         
        for (int i = n - 2; i >= 0; i--) {
 
            cur_max = Math.max(arr[i], cur_max + arr[i]);
            max_so_far = Math.max(max_so_far, cur_max);
 
            // storing current maximum from ith, in
            // backward array
            bw[i] = cur_max;
        }
 
        /* Initializing final ans by max_so_far so that,
        case when no element is removed to get max sum
        subarray is also handled */
        int fans = max_so_far;
 
        // choosing maximum ignoring ith element
        for (int i = 1; i < n - 1; i++)
            fans = Math.max(fans, fw[i - 1] + bw[i + 1]);
 
        return fans;
    }
     
    // Driver code
    public static void main(String arg[])
    {
        int arr[] = { -2, -3, 4, -1, -2, 1, 5, -3 };
        int n = arr.length;
         
        System.out.print(maxSumSubarrayRemovingOneEle(
                                             arr, n));
    }
}
 
// This code is contributed by Anant Agarwal.

Python3

# Python program to get maximum sum subarray removing
# at-most one element
 
# Method returns maximum sum of all subarray where
# removing one element is also allowed
def maxSumSubarrayRemovingOneEle(arr, n):
    # Maximum sum subarrays in forward and backward
    # directions
    fw = [0 for k in range(n)]
    bw = [0 for k in range(n)]
  
    # Initialize current max and max so far.
    cur_max, max_so_far = arr[0], arr[0]
    fw[0] = cur_max
  
    # calculating maximum sum subarrays in forward
    # direction
    for i in range(1,n):
        cur_max = max(arr[i], cur_max + arr[i])
        max_so_far = max(max_so_far, cur_max)
  
        # storing current maximum till ith, in
        # forward array
        fw[i] = cur_max
  
    # calculating maximum sum subarrays in backward
    # direction
    cur_max = max_so_far = bw[n-1] = arr[n-1]
    i = n-2
    while i >= 0:
        cur_max = max(arr[i], cur_max + arr[i])
        max_so_far = max(max_so_far, cur_max)
  
        # storing current maximum from ith, in
        # backward array
        bw[i] = cur_max
        i -= 1
  
    #  Initializing final ans by max_so_far so that,
    #  case when no element is removed to get max sum
    #  subarray is also handled
    fans = max_so_far
  
    #  choosing maximum ignoring ith element
    for i in range(1,n-1):
        fans = max(fans, fw[i - 1] + bw[i + 1])
  
    return fans
  
#  Driver code to test above methods
arr = [-2, -3, 4, -1, -2, 1, 5, -3]
n = len(arr)
print (maxSumSubarrayRemovingOneEle(arr, n))
 
# Contributed by: Afzal_Saan

C#

// C# program to get maximum sum subarray
// removing at-most one element
using System;
class GFG {
     
    // Method returns maximum sum of all subarray where
    // removing one element is also allowed
    static int maxSumSubarrayRemovingOneEle(int []arr,
                                                int n)
    {
         
        // Maximum sum subarrays in forward and
        // backward directions
        int []fw = new int[n];
        int []bw = new int[n];
 
        // Initialize current max and max so far.
        int cur_max = arr[0], max_so_far = arr[0];
 
        // calculating maximum sum subarrays in forward
        // direction
        fw[0] = arr[0];
 
        for (int i = 1; i < n; i++) {
 
            cur_max = Math.Max(arr[i], cur_max + arr[i]);
            max_so_far = Math.Max(max_so_far, cur_max);
 
            // storing current maximum till ith, in
            // forward array
            fw[i] = cur_max;
        }
 
        // calculating maximum sum subarrays in backward
        // direction
        cur_max = max_so_far = bw[n - 1] = arr[n - 1];
         
        for (int i = n - 2; i >= 0; i--) {
 
            cur_max = Math.Max(arr[i], cur_max + arr[i]);
            max_so_far = Math.Max(max_so_far, cur_max);
 
            // storing current maximum from ith, in
            // backward array
            bw[i] = cur_max;
        }
 
        /* Initializing final ans by max_so_far so that,
        case when no element is removed to get max sum
        subarray is also handled */
        int fans = max_so_far;
 
        // choosing maximum ignoring ith element
        for (int i = 1; i < n - 1; i++)
            fans = Math.Max(fans, fw[i - 1] + bw[i + 1]);
 
        return fans;
    }
     
    // Driver code
    public static void Main()
    {
        int []arr = { -2, -3, 4, -1, -2, 1, 5, -3 };
        int n = arr.Length;
         
        Console.WriteLine(maxSumSubarrayRemovingOneEle(
                                            arr, n));
    }
}
 
// This code is contributed by anuj_67.

PHP

<?php
// PHP program to get maximum
// sum subarray removing
// at-most one element
 
// Method returns maximum sum
// of all subarray where removing
// one element is also allowed
function maxSumSubarrayRemovingOneEle( $arr, $n)
{
    // Maximum sum subarrays in
    // forward and backward directions
    $fw = array(); $bw = array();
 
    // Initialize current
    // max and max so far.
    $cur_max = $arr[0];
    $max_so_far = $arr[0];
 
    // calculating maximum sum
    // subarrays in forward direction
    $fw[0] = $arr[0];
    for ($i = 1; $i < $n; $i++)
    {
        $cur_max = max($arr[$i],
                       $cur_max + $arr[$i]);
        $max_so_far = max($max_so_far,
                          $cur_max);
 
        // storing current maximum till
        // ith, in forward array
        $fw[$i] = $cur_max;
    }
 
    // calculating maximum sum
    // subarrays in backward direction
    $cur_max = $max_so_far =
    $bw[$n - 1] = $arr[$n - 1];
    for ( $i = $n - 2; $i >= 0; $i--)
    {
        $cur_max = max($arr[$i],
                       $cur_max + $arr[$i]);
        $max_so_far = max($max_so_far,
                          $cur_max);
 
        // storing current maximum from
        // ith, in backward array
        $bw[$i] = $cur_max;
    }
 
    /* Initializing final ans by
        max_so_far so that, case
        when no element is removed
        to get max sum subarray is
        also handled */
    $fans = $max_so_far;
 
    // choosing maximum
    // ignoring ith element
    for ($i = 1; $i < $n - 1; $i++)
        $fans = max($fans, $fw[$i - 1] +
                           $bw[$i + 1]);
 
    return $fans;
}
 
// Driver Code
$arr = array(-2, -3, 4, -1,
             -2, 1, 5, -3);
$n = count($arr);
echo maxSumSubarrayRemovingOneEle($arr, $n);
 
// This code is contributed by anuj_67.
?>

Javascript

<script>
 
// JavaScript program to get maximum sum subarray
// removing at-most one element
  
// Method returns maximum sum of all subarray where
// removing one element is also allowed
function maxSumSubarrayRemovingOneEle(arr, n)
{
     
    // Maximum sum subarrays in forward and
    // backward directions
    let fw = [];
    let bw = [];
 
    // Initialize current max and max so far.
    let cur_max = arr[0], max_so_far = arr[0];
 
    // calculating maximum sum subarrays in forward
    // direction
    fw[0] = arr[0];
 
    for(let i = 1; i < n; i++)
    {
        cur_max = Math.max(arr[i], cur_max + arr[i]);
        max_so_far = Math.max(max_so_far, cur_max);
 
        // Storing current maximum till ith,
        // in forward array
        fw[i] = cur_max;
    }
 
    // Calculating maximum sum subarrays
    // in backward direction
    cur_max = max_so_far = bw[n - 1] = arr[n - 1];
       
    for(let i = n - 2; i >= 0; i--)
    {
        cur_max = Math.max(arr[i], cur_max + arr[i]);
        max_so_far = Math.max(max_so_far, cur_max);
 
        // Storing current maximum from ith, in
        // backward array
        bw[i] = cur_max;
    }
 
    /* Initializing final ans by max_so_far so that,
    case when no element is removed to get max sum
    subarray is also handled */
    let fans = max_so_far;
 
    // Choosing maximum ignoring ith element
    for(let i = 1; i < n - 1; i++)
        fans = Math.max(fans, fw[i - 1] +
                              bw[i + 1]);
 
    return fans;
}
 
// Driver Code
let arr = [ -2, -3, 4, -1, -2, 1, 5, -3 ];
let n = arr.length;
       
document.write(
    maxSumSubarrayRemovingOneEle(arr, n));
   
</script>

Producción : 

9

Tiempo Complejidad : O(n) 
Espacio Auxiliar : O(n)

Este artículo es una contribución de Vinish Thanai. Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks. 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 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 *