Maximum Subarray Sum possible by replacing an Array element by its Square
Last Updated :
14 Apr, 2023
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++
#include <bits/stdc++.h>
using namespace std;
int getMaxSum( int a[], int n)
{
int dp[n][2];
dp[0][0] = a[0];
dp[0][1] = a[0] * a[0];
int max_sum = max(dp[0][0], dp[0][1]);
for ( int i = 1; i < n; i++)
{
dp[i][0] = max(a[i],
dp[i - 1][0] + a[i]);
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]);
max_sum = max(max_sum, dp[i][1]);
max_sum = max(max_sum, dp[i][0]);
}
return max_sum;
}
int32_t main()
{
int n = 5;
int a[] = { 1, -5, 8, 12, -8 };
cout << getMaxSum(a, n) << endl;
return 0;
}
|
Java
import java.io.*;
class GFG {
public static int getMaxSum( int a[], int n)
{
int dp[][] = new int [n][ 2 ];
dp[ 0 ][ 0 ] = a[ 0 ];
dp[ 0 ][ 1 ] = a[ 0 ] * a[ 0 ];
int max_sum = Math.max(dp[ 0 ][ 0 ], dp[ 0 ][ 1 ]);
for ( int i = 1 ; i < n; i++) {
dp[i][ 0 ] = Math.max(a[i],
dp[i - 1 ][ 0 ] + a[i]);
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]);
max_sum = Math.max(max_sum, dp[i][ 1 ]);
max_sum = Math.max(max_sum, dp[i][ 0 ]);
}
return max_sum;
}
public static void main(String[] args)
{
int n = 5 ;
int a[] = { 1 , - 5 , 8 , 12 , - 8 };
System.out.println(getMaxSum(a, n));
}
}
|
Python3
def getMaxSum(a, n):
dp = [[ 0 for x in range ( 2 )]
for y in range (n)]
dp[ 0 ][ 0 ] = a[ 0 ]
dp[ 0 ][ 1 ] = a[ 0 ] * a[ 0 ]
max_sum = max (dp[ 0 ][ 0 ], dp[ 0 ][ 1 ])
for i in range ( 1 , n):
dp[i][ 0 ] = max (a[i],
dp[i - 1 ][ 0 ] + a[i])
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])
max_sum = max (max_sum, dp[i][ 1 ])
max_sum = max (max_sum, dp[i][ 0 ])
return max_sum
n = 5
a = [ 1 , - 5 , 8 , 12 , - 8 ]
print (getMaxSum(a, n))
|
C#
using System;
class GFG{
public static int getMaxSum( int []a, int n)
{
int [,]dp = new int [n, 2];
dp[0, 0] = a[0];
dp[0, 1] = a[0] * a[0];
int max_sum = Math.Max(dp[0, 0], dp[0, 1]);
for ( int i = 1; i < n; i++)
{
dp[i, 0] = Math.Max(a[i],
dp[i - 1, 0] + a[i]);
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]);
max_sum = Math.Max(max_sum, dp[i, 1]);
max_sum = Math.Max(max_sum, dp[i, 0]);
}
return max_sum;
}
public static void Main(String[] args)
{
int n = 5;
int []a = { 1, -5, 8, 12, -8 };
Console.WriteLine(getMaxSum(a, n));
}
}
|
Javascript
<script>
function getMaxSum(a, n)
{
let dp = new Array(n);
for ( var i = 0; i < dp.length; i++) {
dp[i] = new Array(2);
}
dp[0][0] = a[0];
dp[0][1] = a[0] * a[0];
let max_sum = Math.max(dp[0][0], dp[0][1]);
for (let i = 1; i < n; i++) {
dp[i][0] = Math.max(a[i],
dp[i - 1][0] + a[i]);
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]);
max_sum = Math.max(max_sum, dp[i][1]);
max_sum = Math.max(max_sum, dp[i][0]);
}
return max_sum;
}
let n = 5;
let a = [ 1, -5, 8, 12, -8 ];
document.write(getMaxSum(a, n));
</script>
|
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;
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;
}
int main()
{
int n = 5;
int a[] = { 1, -5, 8, 12, -8 };
cout << getMaxSum(a, n) << endl;
return 0;
}
|
Java
import java.io.*;
class GFG {
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;
}
public static void main(String[] args)
{
int n = 5 ;
int a[] = { 1 , - 5 , 8 , 12 , - 8 };
System.out.println(getMaxSum(a, n));
}
}
|
Python3
def getMaxSum(arr, n):
prefix = [ 0 ] * n
prefix[ 0 ] = arr[ 0 ]
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 = 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 ]
print (getMaxSum(a, n))
|
Javascript
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;
}
let n = 5;
let a = [1, -5, 8, 12, -8];
console.log(getMaxSum(a, n));
|
C#
using System;
class GFG {
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;
}
public static void Main( string [] args)
{
int n = 5;
int [] a = { 1, -5, 8, 12, -8 };
Console.WriteLine(GetMaxSum(a, n));
}
}
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...