1911.最大子序列交替和

【LetMeFly】1911.最大子序列交替和

力扣题目链接:https://leetcode.cn/problems/maximum-alternating-subsequence-sum/

一个下标从 0 开始的数组的 交替和 定义为 偶数 下标处元素之  减去 奇数 下标处元素之  。

  • 比方说,数组 [4,2,5,3] 的交替和为 (4 + 5) - (2 + 3) = 4 。

给你一个数组 nums ,请你返回 nums 中任意子序列的 最大交替和 (子序列的下标 重新 从 0 开始编号)。

一个数组的 子序列 是从原数组中删除一些元素后(也可能一个也不删除)剩余元素不改变顺序组成的数组。比方说,[2,7,4] 是 [4,2,3,7,2,1,4] 的一个子序列(加粗元素),但是 [2,4,2] 不是。

 

示例 1:

输入:nums = [4,2,5,3]
输出:7
解释:最优子序列为 [4,2,5] ,交替和为 (4 + 5) - 2 = 7 。

示例 2:

输入:nums = [5,6,7,8]
输出:8
解释:最优子序列为 [8] ,交替和为 8 。

示例 3:

输入:nums = [6,2,1,2,4,5]
输出:10
解释:最优子序列为 [6,1,5] ,交替和为 (6 + 5) - 1 = 10 。

 

提示:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 105

方法一:动态规划(思维)

从头到尾遍历一遍nums数组,使用两个变量even和odd分别记录“子序列”的结尾为偶数下标 和 奇数下标 时的最优解。

遍历过程中,$even = max(even, odd + nums[i])$,$odd = max(odd, even - nums[i])$

最终返回$\max (odd, even)$即可。

初始值怎么确定?

初始值可以设置为遍历到下标为$0$时候的状态,即:$even = nums[0], odd = 0$。之后从下标$1$开始遍历。

为什么不需要even, newEven, odd, newOdd?even的值修改后不会影响odd的值吗?

如果使用newEven和newOdd,则有:

1
2
3
newEven = max(even, odd + nums[i]);   // line1
newOdd = max(odd, even - nums[i]); // line2
even = newEven, odd = newOdd; // line3

执行过line1后,newEven的值一共有两种情况:

  • $even \geq odd + nums[i]$,则$newEven = even$,使用不使用newEven都一样
  • $even < odd + nums[i]$,则$newEven = odd + nums[i]$,$\max(odd, newEven - nums[i]) = \max(odd, odd) = odd$,因此时$odd > even - nums[i]$,所以$max(odd, even - nums[i]) = odd$,使用不使用newEven都一样

为什么有的题解返回的是even而不是max(even, odd)?

因为如果以奇数下标结尾的话,最后一定会减去最后的奇数,不可能优于其对应的以偶数结尾的序列。

  • 时间复杂度$O(len(nums))$
  • 空间复杂度$O(1)$

AC代码

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
typedef long long ll;

class Solution {
public:
ll maxAlternatingSum(vector<int>& nums) {
ll even = nums[0], old = 0;
for (int i = 1; i < nums.size(); i++) {
even = max(even, old + nums[i]);
old = max(old, even - nums[i]);
}
return even;
}
};

Python

1
2
3
4
5
6
7
8
9
# from typing import List

class Solution:
def maxAlternatingSum(self, nums: List[int]) -> int:
even, odd = nums[0], 0
for i in range(1, len(nums)):
even = max(even, odd + nums[i])
odd = max(odd, even - nums[i])
return even

同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/131652316


1911.最大子序列交替和
https://blog.letmefly.xyz/2023/07/11/LeetCode 1911.最大子序列交替和/
作者
Tisfy
发布于
2023年7月11日
许可协议