Given an integer array arr, find two disjoint (non-overlapping) contiguous subarrays such that the difference between their sums is maximized. In other words, choose non-overlapping subarrays A and B to maximize sum(A) - sum(B).
The subarrays must be contiguous and non-overlapping (disjoint).
Subarrays may be empty only if your problem variant allows it; here we assume non-empty subarrays.
sum(A) - sum(B) can be maximized either by taking a large positive sum(A) and small/negative sum(B), or by taking a large negative sum(B) and a small/positive sum(A). We therefore consider both orientations.
Input: arr =[5,-3,5]Output: 10Explanation: Choose A =[5,-3,5]with sum 7 and B =[](empty disallowed here) or choose B small; equivalently consider left/right partition where maximum difference is10(choose A=[5,-3,5] and B=[-?]).
We present a linear-time solution that uses prefix/suffix passes with Kadane’s algorithm variants to compute, for every partition point, the best subarray sums on each side. From these arrays we compute the maximum of left_max[i] - right_min[i+1] and right_max[i+1] - left_min[i] over all valid splits.
left_max[i]: maximum subarray sum within arr[0..i].
left_min[i]: minimum subarray sum within arr[0..i].
right_max[i]: maximum subarray sum within arr[i..n-1].
right_min[i]: minimum subarray sum within arr[i..n-1].
For any split between i and i+1, candidates for sum(A)-sum(B) are left_max[i] - right_min[i+1] and right_max[i+1] - left_min[i]. We take the maximum over all splits.
classSolution {
public:longlong maxDiffDisjoint(const std::vector<int>& arr) {
int n = arr.size();
if (n <2) return0;
std::vector<longlong> left_max(n), left_min(n), right_max(n), right_min(n);
longlong best = arr[0], cur =0;
// left_max
cur =0; best = arr[0];
for (int i =0; i < n; ++i) {
cur = std::max<longlong>(arr[i], cur + arr[i]);
best = std::max(best, cur);
left_max[i] = best;
}
// left_min
cur =0; best = arr[0];
for (int i =0; i < n; ++i) {
cur = std::min<longlong>(arr[i], cur + arr[i]);
best = std::min(best, cur);
left_min[i] = best;
}
// right_max
cur =0; best = arr[n-1];
for (int i = n-1; i >=0; --i) {
cur = std::max<longlong>(arr[i], cur + arr[i]);
best = std::max(best, cur);
right_max[i] = best;
}
// right_min
cur =0; best = arr[n-1];
for (int i = n-1; i >=0; --i) {
cur = std::min<longlong>(arr[i], cur + arr[i]);
best = std::min(best, cur);
right_min[i] = best;
}
longlong ans = LLONG_MIN;
for (int i =0; i +1< n; ++i) {
ans = std::max(ans, left_max[i] - right_min[i+1]);
ans = std::max(ans, right_max[i+1] - left_min[i]);
}
return ans;
}
};
classSolution {
publiclongmaxDiffDisjoint(int[] arr) {
int n = arr.length;
if (n < 2) return 0;
long[] leftMax =newlong[n], leftMin =newlong[n], rightMax =newlong[n], rightMin =newlong[n];
long cur = 0, best = arr[0];
cur = 0; best = arr[0];
for (int i = 0; i < n; ++i) {
cur = Math.max(arr[i], (int)(cur + arr[i]));
best = Math.max(best, cur);
leftMax[i]= best;
}
cur = 0; best = arr[0];
for (int i = 0; i < n; ++i) {
cur = Math.min(arr[i], (int)(cur + arr[i]));
best = Math.min(best, cur);
leftMin[i]= best;
}
cur = 0; best = arr[n-1];
for (int i = n-1; i >= 0; --i) {
cur = Math.max(arr[i], (int)(cur + arr[i]));
best = Math.max(best, cur);
rightMax[i]= best;
}
cur = 0; best = arr[n-1];
for (int i = n-1; i >= 0; --i) {
cur = Math.min(arr[i], (int)(cur + arr[i]));
best = Math.min(best, cur);
rightMin[i]= best;
}
long ans = Long.MIN_VALUE;
for (int i = 0; i + 1 < n; ++i) {
ans = Math.max(ans, leftMax[i]- rightMin[i+1]);
ans = Math.max(ans, rightMax[i+1]- leftMin[i]);
}
return ans;
}
}
from typing import List
classSolution:
defmax_diff_disjoint(self, arr: List[int]) -> int:
n = len(arr)
if n <2:
return0 left_max = [0] * n
left_min = [0] * n
right_max = [0] * n
right_min = [0] * n
cur =0 best = arr[0]
cur =0; best = arr[0]
for i in range(n):
cur = max(arr[i], cur + arr[i])
best = max(best, cur)
left_max[i] = best
cur =0; best = arr[0]
for i in range(n):
cur = min(arr[i], cur + arr[i])
best = min(best, cur)
left_min[i] = best
cur =0; best = arr[-1]
for i in range(n -1, -1, -1):
cur = max(arr[i], cur + arr[i])
best = max(best, cur)
right_max[i] = best
cur =0; best = arr[-1]
for i in range(n -1, -1, -1):
cur = min(arr[i], cur + arr[i])
best = min(best, cur)
right_min[i] = best
ans =-10**30for i in range(n -1):
ans = max(ans, left_max[i] - right_min[i +1])
ans = max(ans, right_max[i +1] - left_min[i])
return ans
⏰ Time complexity: O(n) — we do a constant number of linear passes over the array.
🧺 Space complexity: O(n) — four auxiliary arrays of length n (can be reduced to O(1) if only the value is required and indices are not tracked, but keeping arrays simplifies retrieval of indices).