We need to find a contiguous subarray whose sum has the largest absolute value. That means we care about both the maximum positive sum and the minimum negative sum (most negative), because taking the absolute value of a very negative sum could give us a larger result than the maximum positive sum.
For example, if the maximum subarray sum is 5 but the minimum subarray sum is -8, then the maximum absolute sum is 8, not 5. So this problem is really asking: find both the maximum subarray sum and the minimum subarray sum, then return whichever has a larger absolute value.
This is a twist on the classic Maximum Subarray problem (Kadane's algorithm). Instead of just tracking the maximum, we need to track the minimum too.
1 <= nums.length <= 10^5: With n up to 100,000, we need an O(n log n) solution or better. An O(n^2) brute force checking all subarrays would be 10 billion operations, which is too slow.-10^4 <= nums[i] <= 10^4: Values are bounded, so the maximum possible subarray sum is 10^5 * 10^4 = 10^9, which fits in a 32-bit integer. No overflow concerns in most languages.Check every possible subarray, compute its sum, take the absolute value, and track the maximum. For each starting index, extend the subarray one element at a time and keep a running sum so each new sum is computed in O(1) from the previous one.
maxAbsSum = 0.i from 0 to n-1, initialize currentSum = 0.j from i to n-1, add nums[j] to currentSum.maxAbsSum = max(maxAbsSum, abs(currentSum)).maxAbsSum.Loading animation...
The brute force checks every subarray, which is too slow for n up to 10^5. Both the maximum and minimum subarray sums can be found in a single linear pass instead.
The maximum absolute subarray sum is either the maximum subarray sum or the absolute value of the minimum subarray sum, whichever is larger. abs(sum) is large when sum is far from zero in either direction, so we need both extremes.
Kadane's algorithm finds the maximum subarray sum in O(n) by maintaining a running sum and starting a fresh subarray whenever the running sum drops below the current element (a negative prefix only lowers future sums). The same algorithm with the comparisons flipped tracks the minimum subarray sum. Both run in the same single pass.
Kadane's algorithm maintains the best subarray sum ending at each position. At every element it chooses between two options: extend the previous subarray by adding the current element, or start a new subarray at the current element. The maximum version takes whichever is larger, max(num, currentMax + num); the minimum version takes whichever is smaller. Extending only helps the maximum when the previous running sum is positive, which is exactly when currentMax + num exceeds num, so the max comparison handles the reset automatically.
maxSum and minSum then record the best value of currentMax and currentMin over all positions, giving the global maximum and minimum subarray sums. The answer is max(maxSum, abs(minSum)).
maxSum = 0, minSum = 0, currentMax = 0, currentMin = 0.currentMax = max(num, currentMax + num) (standard Kadane's).maxSum = max(maxSum, currentMax).currentMin = min(num, currentMin + num) (inverted Kadane's).minSum = min(minSum, currentMin).max(maxSum, abs(minSum)).Loading animation...
Kadane's is already optimal. A prefix-sum view of the same problem reaches the answer through a different argument and shorter code.
The sum of subarray nums[l..r] equals prefix[r+1] - prefix[l], where prefix[i] is the sum of the first i elements. So the maximum absolute subarray sum is the maximum value of abs(prefix[j] - prefix[i]) over all valid pairs where j > i.
To maximize abs(prefix[j] - prefix[i]), we want the largest possible gap between any two prefix sums. That gap is max(prefix) - min(prefix). There is no need to store the entire prefix sum array: we track the running prefix sum and keep the maximum and minimum values seen so far.
The absolute subarray sum abs(prefix[j] - prefix[i]) is largest when the two prefix sums are as far apart as possible, which means one is the global maximum and the other the global minimum of the prefix sequence. Whichever of the two has the larger index becomes prefix[j], so a valid subarray with j > i always exists between them, and its absolute sum is maxPrefix - minPrefix. Their order in the array does not matter.
Both maxPrefix and minPrefix start at 0 because the prefix sequence begins with prefix[0] = 0, the empty prefix. This keeps subarrays that start at index 0 in scope and also covers the empty subarray, whose absolute sum is 0.
prefixSum = 0, maxPrefix = 0, minPrefix = 0.prefixSum.maxPrefix = max(maxPrefix, prefixSum).minPrefix = min(minPrefix, prefixSum).maxPrefix - minPrefix.Loading animation...