1911. 最大交替子序列和

子序列的最大交替和 — 动态规划详解

题目描述

给定一个数组 nums,定义其交替和为:数组中偶数下标元素之和减去奇数下标元素之和(下标从 0 开始)。

例如,数组 [4, 2, 5, 3] 的交替和为 (4 + 5) - (2 + 3) = 4

现在,给定数组 nums,请你找到它的任意子序列,使得该子序列(重新编号,下标从 0 开始)的交替和最大,返回这个最大交替和。

  • 子序列定义:从原数组中删除一些元素后,剩下元素顺序不变组成的数组。
  • 你可以选择不删除任何元素,也可以删除任意多个元素。
  • 子序列的下标重新从 0 开始编号,交替和计算基于子序列的重新编号。

示例

示例 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. 子序列下标是重新编号的,意味着我们自己决定哪些元素是偶数位,哪些是奇数位。
  2. 需要在遍历时动态维护“以当前元素为偶数位的最大交替和”和“以当前元素为奇数位的最大交替和”。

解题方法

动态规划思路

设两个变量:

  • even:当前以偶数下标结尾的最大交替和。
  • odd:当前以奇数下标结尾的最大交替和。

初始时:

even = 0
odd = 0

遍历数组每个元素 num

  • 当前元素可以作为偶数下标项,此时的最大交替和可以是:
    • 保持之前的 even 不变(不选当前元素),或者
    • 在之前的以奇数下标结尾的序列后接上当前元素:odd + num

因此:

new_even = max(even, odd + num)
  • 当前元素可以作为奇数下标项,此时的最大交替和可以是:
    • 保持之前的 odd 不变(不选当前元素),或者
    • 在之前的以偶数下标结尾的序列后接上当前元素,此时交替和要减去这个元素:
new_odd = max(odd, even - num)

最后更新:

even, odd = new_even, new_odd

遍历结束后,even 即为最大交替和。


代码实现

class Solution:
    def maxAlternatingSum(self, nums: List[int]) -> int:
        even = 0
        odd = 0
        for num in nums:
            new_even = max(even, odd + num)
            new_odd = max(odd, even - num)
            even, odd = new_even, new_odd
        return even

复杂度分析

  • 时间复杂度:O(n),遍历一次数组。
  • 空间复杂度:O(1),只用两个变量存储状态。

示例说明

以示例 [4,2,5,3] 为例:

  • 初始:even = 0, odd = 0
  1. num=4:
    • new_even = max(0, 0+4) = 4
    • new_odd = max(0, 0-4) = 0
    • 更新:even=4, odd=0
  2. num=2:
    • new_even = max(4, 0+2) = 4
    • new_odd = max(0, 4-2) = 2
    • 更新:even=4, odd=2
  3. num=5:
    • new_even = max(4, 2+5) = 7
    • new_odd = max(2, 4-5) = 2
    • 更新:even=7, odd=2
  4. num=3:
    • new_even = max(7, 2+3) = 7
    • new_odd = max(2, 7-3) = 4
    • 更新:even=7, odd=4

最终最大交替和是 even = 7

对应子序列 [4, 2, 5],交替和 = 4 + 5 - 2 = 7。


方法对比与分析

  • 暴力搜索:遍历所有子序列,时间复杂度指数级,无法接受。
  • 贪心:交替和的定义复杂,难以直接贪心选择。
  • 动态规划:通过维护两个状态,巧妙求解,时间与空间都最优。

该动态规划算法是此问题的经典且最优解法,适合大规模输入。


拓展

  • 如果想恢复最大交替和对应的子序列,需要在状态转移时额外记录决策路径。
  • 本题也可以类比为“交替加减最大和”问题的变种,动态规划思路通用。

总结

本题通过巧妙设计“偶数下标最大和”和“奇数下标最大和”两个状态变量,实现了对最大交替和子序列的高效求解。

动态规划不仅让我们在 O(n) 时间内解决问题,也带来思路上的清晰与简洁,值得学习和掌握。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值