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: 9
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 memoization 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> |
152
Time Complexity: O(N)
Auxiliary Space: O(N)
Prefix-Suffix Sum approach :
- Firstly, create a prefix sum array such that at i max prefix sum is stored.
- Secondly, create a suffix sum array such that at i max suffix sum is stored.
- After that simply iterate and check for each i few conditions -:
These two conditions should be checked firstly.
- arr[0]*arr[0],
- arr[n-1]*arr[n-1]
Then check these 4 conditions for each i -:
- prefix[i-1] + arr[i]*arr[i] + suffix[i+1],
- arr[i]*arr[i] + suffix[i+1],
- prefix[i-1] + arr[i]*arr[i],
- arr[i]*arr[i],
Then max of all these will be the answer.
Below is the code to implement the same:
C++
#include <algorithm> #include <iostream> using namespace std; // Function to find the maximum subarray sum possible int getMaxSum( int arr[], int n) { int prefix[n]; prefix[0] = arr[0]; for ( int i = 1; i < n; i++) { prefix[i] = max(arr[i], prefix[i - 1] + arr[i]); } int suffix[n]; suffix[n - 1] = arr[n - 1]; for ( int i = n - 2; i >= 0; i--) { suffix[i] = max(arr[i], suffix[i + 1] + arr[i]); } int max = arr[0] * arr[0]; max = std::max(max, arr[n - 1] * arr[n - 1]); for ( int i = 1; i < n - 1; i++) { max = std::max(max, prefix[i - 1] + arr[i] * arr[i] + suffix[i + 1]); max = std::max(max, arr[i] * arr[i] + suffix[i + 1]); max = std::max(max, prefix[i - 1] + arr[i] * arr[i]); max = std::max(max, arr[i] * arr[i]); } return max; } // Driver code int main() { int n = 5; int a[] = { 1, -5, 8, 12, -8 }; // Function Calling cout << getMaxSum(a, n) << endl; return 0; } |
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 [] arr, int n) { int [] prefix = new int [n]; prefix[ 0 ] = arr[ 0 ]; for ( int i = 1 ; i < n; i++) { prefix[i] = Math.max(arr[i], prefix[i - 1 ] + arr[i]); } int [] suffix = new int [n]; suffix[n - 1 ] = arr[n - 1 ]; for ( int i = n - 2 ; i >= 0 ; i--) { suffix[i] = Math.max(arr[i], suffix[i + 1 ] + arr[i]); } int max = arr[ 0 ] * arr[ 0 ]; max = Math.max(max, arr[n - 1 ] * arr[n - 1 ]); for ( int i = 1 ; i < n - 1 ; i++) { max = Math.max(max, prefix[i - 1 ] + arr[i] * arr[i] + suffix[i + 1 ]); max = Math.max(max, arr[i] * arr[i] + suffix[i + 1 ]); max = Math.max(max, prefix[i - 1 ] + arr[i] * arr[i]); max = Math.max(max, arr[i] * arr[i]); } return max; } // 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)); } } // This code is contributed by vishalkumarsahu04 |
Python3
#Function to find maximum subarray sum possible after squaring def getMaxSum(arr, n): prefix = [ 0 ] * n prefix[ 0 ] = arr[ 0 ] #Prefix used to store max of (current value and prefix value at that index) for i in range ( 1 , n): prefix[i] = max (arr[i], prefix[i - 1 ] + arr[i]) suffix = [ 0 ] * n suffix[n - 1 ] = arr[n - 1 ] for i in range (n - 2 , - 1 , - 1 ): suffix[i] = max (arr[i], suffix[i + 1 ] + arr[i]) #max_val storing the max value of subarray sum after squaring max_val = arr[ 0 ] * arr[ 0 ] max_val = max (max_val, arr[n - 1 ] * arr[n - 1 ]) for i in range ( 1 , n - 1 ): max_val = max (max_val, prefix[i - 1 ] + arr[i] * arr[i] + suffix[i + 1 ]) max_val = max (max_val, arr[i] * arr[i] + suffix[i + 1 ]) max_val = max (max_val, prefix[i - 1 ] + arr[i] * arr[i]) max_val = max (max_val, arr[i] * arr[i]) return max_val n = 5 a = [ 1 , - 5 , 8 , 12 , - 8 ] #Function call print (getMaxSum(a, n)) #This code is contributed by Tejas Gundale |
Javascript
// Javascript Program to implement // the above approach // Function to find the maximum subarray // sum possible function getMaxSum(arr, n) { let prefix = new Array(n);; prefix[0] = arr[0]; for (let i = 1; i < n; i++) { prefix[i] = Math.max(arr[i], prefix[i - 1] + arr[i]); } let suffix = new Array(n); suffix[n - 1] = arr[n - 1]; for (let i = n - 2; i >= 0; i--) { suffix[i] = Math.max(arr[i], suffix[i + 1] + arr[i]); } let max = arr[0] * arr[0]; max = Math.max(max, arr[n - 1] * arr[n - 1]); for (let i = 1; i < n - 1; i++) { max = Math.max(max, prefix[i - 1] + arr[i] * arr[i] + suffix[i + 1]); max = Math.max(max, arr[i] * arr[i] + suffix[i + 1]); max = Math.max(max, prefix[i - 1] + arr[i] * arr[i]); max = Math.max(max, arr[i] * arr[i]); } return max; } // Driver Code let n = 5; let a = [1, -5, 8, 12, -8]; // Function call console.log(getMaxSum(a, n)); // This code is contributed by Nidhi goel. |
C#
using System; class GFG { // Function to find the maximum subarray // sum possible public static int GetMaxSum( int [] arr, int n) { int [] prefix = new int [n]; prefix[0] = arr[0]; for ( int i = 1; i < n; i++) { prefix[i] = Math.Max(arr[i], prefix[i - 1] + arr[i]); } int [] suffix = new int [n]; suffix[n - 1] = arr[n - 1]; for ( int i = n - 2; i >= 0; i--) { suffix[i] = Math.Max(arr[i], suffix[i + 1] + arr[i]); } int max = arr[0] * arr[0]; max = Math.Max(max, arr[n - 1] * arr[n - 1]); for ( int i = 1; i < n - 1; i++) { max = Math.Max(max, prefix[i - 1] + arr[i] * arr[i] + suffix[i + 1]); max = Math.Max(max, arr[i] * arr[i] + suffix[i + 1]); max = Math.Max(max, prefix[i - 1] + arr[i] * arr[i]); max = Math.Max(max, arr[i] * arr[i]); } return max; } // 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)); } } |
152
Time Complexity: O(N)
Auxiliary Space: O(N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!