原文链接: https://leetcode-cn.com/problems/maximum-alternating-subsequence-sum
英文原文
The alternating sum of a 0-indexed array is defined as the sum of the elements at even indices minus the sum of the elements at odd indices.
- For example, the alternating sum of
[4,2,5,3]
is(4 + 5) - (2 + 3) = 4
.
Given an array nums
, return the maximum alternating sum of any subsequence of nums
(after reindexing the elements of the subsequence).
A subsequence of an array is a new array generated from the original array by deleting some elements (possibly none) without changing the remaining elements' relative order. For example, [2,7,4]
is a subsequence of [4,2,3,7,2,1,4]
(the underlined elements), while [2,4,2]
is not.
Example 1:
Input: nums = [4,2,5,3] Output: 7 Explanation: It is optimal to choose the subsequence [4,2,5] with alternating sum (4 + 5) - 2 = 7.
Example 2:
Input: nums = [5,6,7,8] Output: 8 Explanation: It is optimal to choose the subsequence [8] with alternating sum 8.
Example 3:
Input: nums = [6,2,1,2,4,5] Output: 10 Explanation: It is optimal to choose the subsequence [6,1,5] with alternating sum (6 + 5) - 1 = 10.
Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= 105
中文题目
一个下标从 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
通过代码
高赞题解
定义 $f[i][0]$ 表示前 $i$ 个数中长为偶数的子序列的最大交替和,$f[i][1]$ 表示前 $i$ 个数中长为奇数的子序列的最大交替和。
初始时有 $f[0][0] = 0$,$f[0][1] = -\infty$。
对于第 $i$ 个数,有选或不选两种决策。
对于 $f[i+1][0]$,若不选第 $i$ 个数,则从 $f[i][0]$ 转移过来,否则从 $f[i][1]-\textit{nums}[i]$ 转移过来,取二者最大值。
对于 $f[i+1][1]$,若不选第 $i$ 个数,则从 $f[i][1]$ 转移过来,否则从 $f[i][0]+\textit{nums}[i]$ 转移过来,取二者最大值。
因此得到如下状态转移方程:
$$
\begin{aligned}
&f[i+1][0] = \max(f[i][0], f[i][1]-\textit{nums}[i])\
&f[i+1][1] = \max(f[i][1], f[i][0]+\textit{nums}[i])
\end{aligned}
$$
记 $\textit{nums}$ 的长度为 $n$,$\textit{nums}$ 子序列的最大交替和为 $\max(f[n][0],f[n][1])$。
注意到,由于长度为偶数的子序列的最后一个元素在交替和中需要取负号,在 $\textit{nums}$ 的元素均为正数的情况下,那不如不计入该元素。
因此 $f[n][1]>f[n][0]$ 必然成立,于是返回 $f[n][1]$ 即可。
代码实现时可以用滚动数组优化。
func maxAlternatingSum(nums []int) int64 {
f := [2]int{0, math.MinInt64 / 2} // 除 2 防止计算时溢出
for _, v := range nums {
f = [2]int{max(f[0], f[1]-v), max(f[1], f[0]+v)}
}
return int64(f[1])
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
统计信息
通过次数 | 提交次数 | AC比率 |
---|---|---|
3704 | 6542 | 56.6% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|