题目描述:
链接:https://leetcode-cn.com/problems/maximum-alternating-subsequence-sum/solution/zui-da-zi-xu-lie-jiao-ti-he-by-leetcode-epqrk/
简单的想法,利用动态规划,分两种情况讨论,一种是当前数组是偶数下标结尾,
另一种是当前数据是奇数下标结尾,可以写出如下递推公式:
奇数:odd[i]=max{even[i−1]−nums[i],odd[i−1]}
偶数:even[i]=max{odd[i−1]+nums[i],even[i−1]}
为了避免 i-1的时候出现下标不存在,我们从 下标为1的时候开始遍历,需要注意的是将odd[0] 置为0
代码如下:
class Solution {
long long maxAlternatingSum(vector<int>& nums) {
if (nums.size() == 1) {
return nums[0];
}
vector<int> A;
vector<int> B;
// 边界条件处理
A.push_back(nums[0]);
B.push_back(0);
//B.push_back(nums[1]);
for (int i = 1; i < nums.size(); i++) {
int cur = nums[i];
int max_even = 0;
int max_odd = 0;
for (int j = 0; j < i; j++) {
max_even = max(B[j], max_even) + cur; // 偶数结尾,为最大奇数结尾相加
max_odd = max(A[i]-cur, max_odd); // 奇数结尾,为最大偶数结尾相减
}
A.push_back(max_even);
B.push_back(max_odd);
}
// return max(A[nums.size()-1], B[nums.size()-1]);
return A.size();
}
};
这种方式提交出现了:
heap-buffer-overflow的报错,堆内存使用太多
每一步其实找到最大的odd、even值就可以了,使用两个常数代替两个一维数组
改进代码如下:
class Solution {
public:
long long maxAlternatingSum(vector<int>& nums) {
int n = nums.size();
long long odd = 0, even = nums[0];
for (int i = 1; i < n; ++i) {
tie(odd, even) = tuple{max(even - nums[i], odd), max(odd + nums[i], even)};
}
return even;
}
};
```