Given an array of positive integers nums
, you are to select a subsequence (not necessarily contiguous) where the sum of the elements taken at odd indices of the subsequence is subtracted by the sum of the elements taken at even indices (using 1-based indexing within the subsequence). The goal is to maximize this alternating sum.
Formally, for a subsequence seq
of nums
, the alternating sum is defined as:
seq[0] - seq[1] + seq[2] - seq[3] + ...
Return the maximum possible alternating sum of any subsequence of nums
.
nums
can be used at most once.At first glance, it seems like we might need to check all possible subsequences, compute the alternating sum for each, and keep track of the maximum. This brute-force approach, however, is infeasible for larger arrays due to the exponential number of subsequences.
To optimize, we notice that the alternating sum depends on the relative positions (odd/even) within the chosen subsequence, not the original array. We can use dynamic programming to keep track of two states as we iterate:
At each step, we decide whether to include the current number in the subsequence (and at which position), or to skip it.
We use dynamic programming with two variables to track the best possible sums:
even
= 0 (no numbers chosen yet, so sum is 0)odd
= 0 (no numbers chosen yet, so sum is 0)nums
:
x
in nums
:
x
as the next odd index in the subsequence, our alternating sum increases by x
(since it's the turn to add), so update even = max(even, odd + x)
.
x
as the next even index, our alternating sum decreases by x
(since it's the turn to subtract), so update odd = max(odd, even - x)
.
even
after processing the entire array.
This approach is efficient because it only needs to keep track of two variables and updates them in constant time for each element.
Let's use nums = [4, 2, 5, 3]
as an example.
even = 0
, odd = 0
The answer is even = 7
. The subsequence [4, 5, 3] gives 4 - 5 + 3 = 2, but [4, 5] gives 4 - 5 = -1, [4, 5, 3] gives 4 - 5 + 3 = 2, [4, 2, 5] gives 4 - 2 + 5 = 7, which is the maximum.
The Maximum Alternating Subsequence Sum problem can be solved efficiently using a simple dynamic programming approach that tracks the best possible alternating sum for subsequences ending at even and odd positions. By updating two variables as we iterate, we avoid the exponential complexity of brute-force and achieve a linear time, constant space solution. The key insight is recognizing the alternating nature of the sum and using state variables to represent the two possible "parities" of the subsequence's length.
class Solution:
def maxAlternatingSum(self, nums):
even = 0
odd = 0
for x in nums:
even = max(even, odd + x)
odd = max(odd, even - x)
return even
class Solution {
public:
long long maxAlternatingSum(vector<int>& nums) {
long long even = 0, odd = 0;
for (int x : nums) {
long long new_even = max(even, odd + x);
long long new_odd = max(odd, even - x);
even = new_even;
odd = new_odd;
}
return even;
}
};
class Solution {
public long maxAlternatingSum(int[] nums) {
long even = 0, odd = 0;
for (int x : nums) {
long newEven = Math.max(even, odd + x);
long newOdd = Math.max(odd, even - x);
even = newEven;
odd = newOdd;
}
return even;
}
}
var maxAlternatingSum = function(nums) {
let even = 0, odd = 0;
for (let x of nums) {
let newEven = Math.max(even, odd + x);
let newOdd = Math.max(odd, even - x);
even = newEven;
odd = newOdd;
}
return even;
};