📜  最多反转两个元素后的最大子数组总和

📅  最后修改于: 2021-05-04 12:48:41             🧑  作者: Mango

给定整数元素的数组arr [] ,任务是在最多更改两个元素的符号之后找到最大可能的子数组总和。

例子:

方法:可以使用动态编程解决此问题。假设数组中有n个元素。我们构建从最小长度到最大长度的解决方案。
在每一步中,我们将长度i的解更改为i + 1。
对于每一步,我们有三种情况:

  1. (最大子数组总和),最多更改0个元素的符号。
  2. (最大子数组总和),最多更改1个元素的符号。
  3. (最多子数组总和),最多更改2个元素的符号。

这些情况彼此使用以前的值。

  • 情况1:我们有两个选择,要么获取当前元素,要么将当前值添加到相同案例的先前值中。我们存储较大的那个。
  • 情况2:我们有两种选择
    1. 我们更改当前元素的符号,然后将其添加到0或以前的case 1值。我们存储较大的那个。
    2. 我们获取数组的当前元素并将其添加到前面的案例2的值中。如果此值大于我们在(a)案例中获得的值,则我们不进行其他更新。
  • 情况3:我们在这里又有两个选择
    1. 我们更改当前元素的符号,并将其添加到先前的情况2值。
    2. 我们将当前元素添加到先前的情况3值中。对于当前情况,将从(a)和(b)获得的较大值存储起来。

我们从这3种情况中更新最大值并将其存储在变量中。
对于每个步骤的每种情况,如果给定数组包含n个元素,则采用二维数组dp [n + 1] [3]。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
#include 
using namespace std;
  
// Function to return the maximum required sub-array sum
int maxSum(int a[], int n)
{
    int ans = 0;
    int* arr = new int[n + 1];
  
    // Creating one based indexing
    for (int i = 1; i <= n; i++)
        arr[i] = a[i - 1];
  
    // 2d array to contain solution for each step
    int** dp = new int*[n + 1];
    for (int i = 0; i <= n; i++)
        dp[i] = new int[3];
    for (int i = 1; i <= n; ++i) {
  
        // Case 1: Choosing current or (current + previous)
        // whichever is smaller
        dp[i][0] = max(arr[i], dp[i - 1][0] + arr[i]);
  
        // Case 2:(a) Altering sign and add to previous case 1 or
        // value 0
        dp[i][1] = max(0, dp[i - 1][0]) - arr[i];
  
        // Case 2:(b) Adding current element with previous case 2
        // and updating the maximum
        if (i >= 2)
            dp[i][1] = max(dp[i][1], dp[i - 1][1] + arr[i]);
  
        // Case 3:(a) Altering sign and add to previous case 2
        if (i >= 2)
            dp[i][2] = dp[i - 1][1] - arr[i];
  
        // Case 3:(b) Adding current element with previous case 3
        if (i >= 3)
            dp[i][2] = max(dp[i][2], dp[i - 1][2] + arr[i]);
  
        // Updating the maximum value of variable ans
        ans = max(ans, dp[i][0]);
        ans = max(ans, dp[i][1]);
        ans = max(ans, dp[i][2]);
    }
  
    // Return the final solution
    return ans;
}
  
// Driver code
int main()
{
    int arr[] = { -5, 3, 2, 7, -8, 3, 7, -9, 10, 12, -6 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << maxSum(arr, n);
  
    return 0;
}


Java
// Java implementation of the approach
  
class GFG
{
    // Function to return the maximum required sub-array sum
    static int maxSum(int []a, int n)
    {
        int ans = 0;
        int [] arr = new int[n + 1];
      
        // Creating one based indexing
        for (int i = 1; i <= n; i++)
            arr[i] = a[i - 1];
      
        // 2d array to contain solution for each step
        int [][] dp = new int [n + 1][3];
        for (int i = 1; i <= n; ++i) 
        {
      
            // Case 1: Choosing current or (current + previous)
            // whichever is smaller
            dp[i][0] = Math.max(arr[i], dp[i - 1][0] + arr[i]);
      
            // Case 2:(a) Altering sign and add to previous case 1 or
            // value 0
            dp[i][1] = Math.max(0, dp[i - 1][0]) - arr[i];
      
            // Case 2:(b) Adding current element with previous case 2
            // and updating the maximum
            if (i >= 2)
                dp[i][1] = Math.max(dp[i][1], dp[i - 1][1] + arr[i]);
      
            // Case 3:(a) Altering sign and add to previous case 2
            if (i >= 2)
                dp[i][2] = dp[i - 1][1] - arr[i];
      
            // Case 3:(b) Adding current element with previous case 3
            if (i >= 3)
                dp[i][2] = Math.max(dp[i][2], dp[i - 1][2] + arr[i]);
      
            // Updating the maximum value of variable ans
            ans = Math.max(ans, dp[i][0]);
            ans = Math.max(ans, dp[i][1]);
            ans = Math.max(ans, dp[i][2]);
        }
      
        // Return the final solution
        return ans;
    }
      
    // Driver code
    public static void main (String[] args) 
    {
        int arr[] = { -5, 3, 2, 7, -8, 3, 7, -9, 10, 12, -6 };
        int n = arr.length;
        System.out.println(maxSum(arr, n));
    }
}
  
// This code is contributed by ihritik


Python3
# Python3 implementation of the approach 
  
# Function to return the maximum 
# required sub-array sum 
def maxSum(a, n): 
  
    ans = 0
    arr = [0] * (n + 1)
      
    # Creating one based indexing
    for i in range(1, n + 1):
        arr[i] = a[i - 1]
  
    # 2d array to contain solution for each step 
    dp = [[0 for i in range(3)] 
             for j in range(n + 1)] 
    for i in range(0, n + 1): 
          
        # Case 1: Choosing current or 
        # (current + previous) whichever is smaller 
        dp[i][0] = max(arr[i], dp[i - 1][0] + arr[i]) 
  
        # Case 2:(a) Altering sign and add to 
        # previous case 1 or value 0 
        dp[i][1] = max(0, dp[i - 1][0]) - arr[i] 
  
        # Case 2:(b) Adding current element with 
        # previous case 2 and updating the maximum 
        if i >= 2: 
            dp[i][1] = max(dp[i][1],
                           dp[i - 1][1] + arr[i]) 
  
        # Case 3:(a) Altering sign and 
        # add to previous case 2 
        if i >= 2: 
            dp[i][2] = dp[i - 1][1] - arr[i] 
  
        # Case 3:(b) Adding current element
        # with previous case 3 
        if i >= 3: 
            dp[i][2] = max(dp[i][2], 
                           dp[i - 1][2] + arr[i]) 
  
        # Updating the maximum value
        # of variable ans 
        ans = max(ans, dp[i][0]) 
        ans = max(ans, dp[i][1]) 
        ans = max(ans, dp[i][2]) 
      
    # Return the final solution 
    return ans 
  
# Driver code 
if __name__ == "__main__":
  
    arr = [-5, 3, 2, 7, -8, 3, 
            7, -9, 10, 12, -6] 
    n = len(arr) 
    print(maxSum(arr, n)) 
  
# This code is contributed by Rituraj Jain


C#
// C# implementation of the approach
using System;
  
class GFG
{
    // Function to return the maximum required sub-array sum
    static int maxSum(int [] a, int n)
    {
        int ans = 0;
        int [] arr = new int[n + 1];
      
        // Creating one based indexing
        for (int i = 1; i <= n; i++)
            arr[i] = a[i - 1];
      
        // 2d array to contain solution for each step
        int [, ] dp = new int [n + 1, 3];
        for (int i = 1; i <= n; ++i) 
        {
      
            // Case 1: Choosing current or (current + previous)
            // whichever is smaller
            dp[i, 0] = Math.Max(arr[i], dp[i - 1, 0] + arr[i]);
      
            // Case 2:(a) Altering sign and add to previous case 1 or
            // value 0
            dp[i, 1] = Math.Max(0, dp[i - 1, 0]) - arr[i];
      
            // Case 2:(b) Adding current element with previous case 2
            // and updating the maximum
            if (i >= 2)
                dp[i, 1] = Math.Max(dp[i, 1], dp[i - 1, 1] + arr[i]);
      
            // Case 3:(a) Altering sign and add to previous case 2
            if (i >= 2)
                dp[i, 2] = dp[i - 1, 1] - arr[i];
      
            // Case 3:(b) Adding current element with previous case 3
            if (i >= 3)
                dp[i, 2] = Math.Max(dp[i, 2], dp[i - 1, 2] + arr[i]);
      
            // Updating the maximum value of variable ans
            ans = Math.Max(ans, dp[i, 0]);
            ans = Math.Max(ans, dp[i, 1]);
            ans = Math.Max(ans, dp[i, 2]);
        }
      
        // Return the final solution
        return ans;
    }
      
    // Driver code
    public static void Main ()
    {
        int [] arr = { -5, 3, 2, 7, -8, 3, 7, -9, 10, 12, -6 };
        int n = arr.Length;
        Console.WriteLine(maxSum(arr, n));
    }
}
  
// This code is contributed by ihritik


PHP
= 2) 
            $dp[$i][1] = max($dp[$i][1], 
                             $dp[$i - 1][1] + $arr[$i]); 
  
        // Case 3:(a) Altering sign and 
        // add to previous case 2 
        if ($i >= 2) 
            $dp[$i][2] = $dp[$i - 1][1] - $arr[$i]; 
  
        // Case 3:(b) Adding current element 
        // with previous case 3 
        if ($i >= 3) 
            $dp[$i][2] = max($dp[$i][2],
                             $dp[$i - 1][2] + $arr[$i]); 
  
        // Updating the maximum value of variable ans 
        $ans = max($ans, $dp[$i][0]); 
        $ans = max($ans, $dp[$i][1]); 
        $ans = max($ans, $dp[$i][2]); 
    } 
  
    // Return the final solution 
    return $ans; 
} 
  
// Driver code 
$arr = array( -5, 3, 2, 7, -8, 3, 
               7, -9, 10, 12, -6 ); 
$n = count($arr) ; 
  
echo maxSum($arr, $n); 
  
// This code is contributed by Ryuga
?>


输出:
61

时间复杂度: O(N)
空间复杂度: O(3*N+N) = O(N)

要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”