Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Maximum Subarray Sum possible by replacing an Array element by its Square

  • Difficulty Level : Hard
  • Last Updated : 09 Jul, 2021

Given an array a[] consisting of N integers, the task is to find the maximum subarray sum that can be obtained by replacing a single array element by its square.

Examples:

Input: a[] = {1, -5, 8, 12, -8} 
Output: 152 
Explanation: 
Replacing 12 by 144, the subarray {8, 144} generates the maximum possible subarray sum in the array.
Input: a[] = {-1, -2, -3} 
Output:
Explanation:

Naive Approach: The simplest approach to solve the problem is to replace every element with its square and for each of them, find the maximum subarray sum using Kadane’s algorithm. Finally, print the maximum possible subarray sum obtained. 
Time Complexity: O(N2
Auxiliary Space: O(1)

Efficient Approach: The above approach can be optimized using Dynamic Programming. Follow the steps below to solve the problem:

  • Initialize memorization table dp[][] where:
  • dp[i][0]: Stores the maximum subarray sum that can be obtained including ith element and without squaring any array element.
  • dp[i][1]: Stores the maximum subarray sum that can be including ith element and squaring one of the array elements
  • Therefore, the recurrence relations are:

dp[i][0] = max(dp[i-1][0] + a[i], a[i]), that is, either extend the previous subarray ending at i – 1th index or start a new subarray from ith index.
dp[i][1] = max(a[i]2, dp[i-1][0] + a[i]2, dp[i-1][1] + a[i]), that is, either start new subarray from ith index or extend previous subarray by adding a[i]2 to dp[i – 1][0] or add a[i] to dp[i – 1][1]
 

Below is the implementation of the above approach:

C++




// C++ program to implement
// the above approach
#include <bits/stdc++.h> 
using namespace std; 
 
// Function to find the maximum subarray
// sum possible
int getMaxSum(int a[], int n)
{
    int dp[n][2];
 
    // Stores sum without squaring
    dp[0][0] = a[0];
 
    // Stores sum squaring
    dp[0][1] = a[0] * a[0];
 
    // Stores the maximum subarray sum
    int max_sum = max(dp[0][0], dp[0][1]);
    for(int i = 1; i < n; i++)
    {
         
        // Either extend the subarray
        // or start a new subarray
        dp[i][0] = max(a[i],
                      dp[i - 1][0] + a[i]);
 
        // Either extend previous squared
        // subarray or start a new subarray
        // by squaring the current element
        dp[i][1] = max(dp[i - 1][1] + a[i],
                               a[i] * a[i]);
 
        dp[i][1] = max(dp[i][1],
                       dp[i - 1][0] +
                       a[i] * a[i]);
 
        // Update maximum subarray sum
        max_sum = max(max_sum, dp[i][1]);
        max_sum = max(max_sum, dp[i][0]);
    }
     
    // Return answer
    return max_sum;
}
     
// Driver Code
int32_t main()
{
    int n = 5;
    int a[] = { 1, -5, 8, 12, -8 };
 
    // Function call
    cout << getMaxSum(a, n) << endl;
 
    return 0;
}
 
// This code is contributed by rutvik_56

Java




// Java Program to implement
// the above approach
import java.io.*;
 
class GFG {
 
    // Function to find the maximum subarray
    // sum possible
    public static int getMaxSum(int a[], int n)
    {
        int dp[][] = new int[n][2];
 
        // Stores sum without squaring
        dp[0][0] = a[0];
 
        // Stores sum squaring
        dp[0][1] = a[0] * a[0];
 
        // Stores the maximum subarray sum
        int max_sum = Math.max(dp[0][0], dp[0][1]);
        for (int i = 1; i < n; i++) {
 
            // Either extend the subarray
            // or start a new subarray
            dp[i][0] = Math.max(a[i],
                                dp[i - 1][0] + a[i]);
 
            // Either extend previous squared
            // subarray or start a new subarray
            // by squaring the current element
            dp[i][1] = Math.max(dp[i - 1][1] + a[i],
                                a[i] * a[i]);
 
            dp[i][1]
                = Math.max(dp[i][1],
                        dp[i - 1][0] + a[i] * a[i]);
 
            // Update maximum subarray sum
            max_sum = Math.max(max_sum, dp[i][1]);
            max_sum = Math.max(max_sum, dp[i][0]);
        }
 
        // Return answer
        return max_sum;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int n = 5;
        int a[] = { 1, -5, 8, 12, -8 };
 
        // Function call
        System.out.println(getMaxSum(a, n));
    }
}

Python3




# Python3 program to implement
# the above approach
 
# Function to find the maximum subarray
# sum possible
def getMaxSum(a, n):
 
    dp = [[0 for x in range(2)]
            for y in range(n)]
 
    # Stores sum without squaring
    dp[0][0] = a[0]
 
    # Stores sum squaring
    dp[0][1] = a[0] * a[0]
 
    # Stores the maximum subarray sum
    max_sum = max(dp[0][0], dp[0][1])
 
    for i in range(1, n):
 
        # Either extend the subarray
        # or start a new subarray
        dp[i][0] = max(a[i],
                    dp[i - 1][0] + a[i])
 
        # Either extend previous squared
        # subarray or start a new subarray
        # by squaring the current element
        dp[i][1] = max(dp[i - 1][1] + a[i],
                        a[i] * a[i])
 
        dp[i][1] = max(dp[i][1],
                    dp[i - 1][0] +
                        a[i] * a[i])
 
        # Update maximum subarray sum
        max_sum = max(max_sum, dp[i][1])
        max_sum = max(max_sum, dp[i][0])
 
    # Return answer
    return max_sum
 
# Driver Code
n = 5
a = [ 1, -5, 8, 12, -8 ]
 
# Function call
print(getMaxSum(a, n))
 
# This code is contributed by Shivam Singh

C#




// C# program to implement
// the above approach
using System;
 
class GFG{
 
// Function to find the maximum subarray
// sum possible
public static int getMaxSum(int []a, int n)
{
    int [,]dp = new int[n, 2];
 
    // Stores sum without squaring
    dp[0, 0] = a[0];
 
    // Stores sum squaring
    dp[0, 1] = a[0] * a[0];
 
    // Stores the maximum subarray sum
    int max_sum = Math.Max(dp[0, 0], dp[0, 1]);
    for(int i = 1; i < n; i++)
    {
         
        // Either extend the subarray
        // or start a new subarray
        dp[i, 0] = Math.Max(a[i],
                        dp[i - 1, 0] + a[i]);
 
        // Either extend previous squared
        // subarray or start a new subarray
        // by squaring the current element
        dp[i, 1] = Math.Max(dp[i - 1, 1] + a[i],
                            a[i] * a[i]);
 
        dp[i, 1] = Math.Max(dp[i, 1],
                            dp[i - 1, 0] +
                            a[i] * a[i]);
 
        // Update maximum subarray sum
        max_sum = Math.Max(max_sum, dp[i, 1]);
        max_sum = Math.Max(max_sum, dp[i, 0]);
    }
 
    // Return answer
    return max_sum;
}
 
// Driver Code
public static void Main(String[] args)
{
    int n = 5;
    int []a = { 1, -5, 8, 12, -8 };
 
    // Function call
    Console.WriteLine(getMaxSum(a, n));
}
}
 
// This code is contributed by PrinciRaj1992

Javascript




<script>
 
// JavaScript program for the above approach
 
  // Function to find the maximum subarray
    // sum possible
    function getMaxSum(a, n)
    {
        let dp = new Array(n);
        // Loop to create 2D array using 1D array
        for (var i = 0; i < dp.length; i++) {
            dp[i] = new Array(2);
        }
   
        // Stores sum without squaring
        dp[0][0] = a[0];
   
        // Stores sum squaring
        dp[0][1] = a[0] * a[0];
   
        // Stores the maximum subarray sum
        let max_sum = Math.max(dp[0][0], dp[0][1]);
        for (let i = 1; i < n; i++) {
   
            // Either extend the subarray
            // or start a new subarray
            dp[i][0] = Math.max(a[i],
                                dp[i - 1][0] + a[i]);
   
            // Either extend previous squared
            // subarray or start a new subarray
            // by squaring the current element
            dp[i][1] = Math.max(dp[i - 1][1] + a[i],
                                a[i] * a[i]);
   
            dp[i][1]
                = Math.max(dp[i][1],
                        dp[i - 1][0] + a[i] * a[i]);
   
            // Update maximum subarray sum
            max_sum = Math.max(max_sum, dp[i][1]);
            max_sum = Math.max(max_sum, dp[i][0]);
        }
   
        // Return answer
        return max_sum;
    }
     
// Driver Code
 
        let n = 5;
        let a = [ 1, -5, 8, 12, -8 ];
   
        // Function call
        document.write(getMaxSum(a, n));
      
</script>
Output: 
152

 

Time Complexity: O(N) 
Auxiliary Space: O(N)
 


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!