Maximum Subarray Sum After One Operation
MediumUpdated: Aug 2, 2025
Practice on:
Problem
You are given an integer array nums. You must perform exactly one operation where you can replace one element nums[i] with nums[i] * nums[i].
Return themaximum possible subarray sum after exactly one operation. The subarray must be non-empty.
Examples
Example 1:
Input: nums = [2,-1,-4,-3]
Output: 17
Explanation: You can perform the operation on index 2 (0-indexed) to make nums = [2,-1,**16** ,-3]. Now, the maximum subarray sum is 2 + -1 + 16 = 17.
Example 2:
Input: nums = [1,-1,1,1,-1,-1,1]
Output: 4
Explanation: You can perform the operation on index 1 (0-indexed) to make nums = [1,**1** ,1,1,-1,-1,1]. Now, the maximum subarray sum is 1 + 1 + 1 + 1 = 4.
Constraints:
1 <= nums.length <= 10^5-10^4 <= nums[i] <= 10^4
Solution
Method 1 – Dynamic Programming (Kadane's Variant)
Intuition
We want the maximum subarray sum after squaring exactly one element. For each position, we can either have not used the operation yet, or have already used it. We use dynamic programming to track both cases as we scan the array.
Approach
- Let
no_opbe the maximum subarray sum ending at the current index without using the operation. - Let
with_opbe the maximum subarray sum ending at the current index having used the operation. - For each index:
- Update
no_opas the max ofnums[i]andno_op + nums[i](Kadane's algorithm). - Update
with_opas the max of:no_op + nums[i]*nums[i](use operation at this index)with_op + nums[i](already used operation before)nums[i]*nums[i](start new subarray with operation at this index)
- Update
- Track the maximum value of
with_opacross all indices.
Code
C++
class Solution {
public:
int maxSumAfterOperation(vector<int>& nums) {
int n = nums.size();
int no_op = 0, with_op = 0, ans = INT_MIN;
for (int i = 0; i < n; ++i) {
with_op = max({no_op + nums[i]*nums[i], with_op + nums[i], nums[i]*nums[i]});
no_op = max(no_op + nums[i], nums[i]);
ans = max(ans, with_op);
}
return ans;
}
};
Go
func maxSumAfterOperation(nums []int) int {
noOp, withOp := 0, 0
ans := nums[0]*nums[0]
for _, x := range nums {
withOp = max(noOp + x*x, withOp + x, x*x)
noOp = max(noOp + x, x)
ans = max(ans, withOp)
}
return ans
}
func max(a, b int) int { if a > b { return a }; return b }
Java
class Solution {
public int maxSumAfterOperation(int[] nums) {
int noOp = 0, withOp = 0, ans = Integer.MIN_VALUE;
for (int x : nums) {
withOp = Math.max(Math.max(noOp + x*x, withOp + x), x*x);
noOp = Math.max(noOp + x, x);
ans = Math.max(ans, withOp);
}
return ans;
}
}
Kotlin
class Solution {
fun maxSumAfterOperation(nums: IntArray): Int {
var noOp = 0; var withOp = 0; var ans = Int.MIN_VALUE
for (x in nums) {
withOp = maxOf(noOp + x*x, withOp + x, x*x)
noOp = maxOf(noOp + x, x)
ans = maxOf(ans, withOp)
}
return ans
}
}
Python
class Solution:
def maxSumAfterOperation(self, nums: list[int]) -> int:
no_op = 0
with_op = 0
ans = float('-inf')
for x in nums:
with_op = max(no_op + x*x, with_op + x, x*x)
no_op = max(no_op + x, x)
ans = max(ans, with_op)
return ans
Rust
impl Solution {
pub fn max_sum_after_operation(nums: Vec<i32>) -> i32 {
let (mut no_op, mut with_op, mut ans) = (0, 0, i32::MIN);
for &x in &nums {
with_op = (no_op + x*x).max(with_op + x).max(x*x);
no_op = (no_op + x).max(x);
ans = ans.max(with_op);
}
ans
}
}
TypeScript
class Solution {
maxSumAfterOperation(nums: number[]): number {
let noOp = 0, withOp = 0, ans = -Infinity;
for (const x of nums) {
withOp = Math.max(noOp + x*x, withOp + x, x*x);
noOp = Math.max(noOp + x, x);
ans = Math.max(ans, withOp);
}
return ans;
}
}
Complexity
- ⏰ Time complexity:
O(n), wherenis the length of nums. We scan the array once. - 🧺 Space complexity:
O(1), only a few variables are used.