1696. 跳跃游戏 VI

目录

跳跃游戏最大得分 —— 动态规划与单调队列优化详解

题目描述

解题分析

解题方法

1. 朴素动态规划

2. 单调队列优化

代码实现

复杂度分析与对比

示例说明

总结


跳跃游戏最大得分 —— 动态规划与单调队列优化详解

题目描述

给定一个下标从 0 开始的整数数组 nums 和一个整数 k,你最初位于数组的第一个元素(下标为 0)。

每一步,你最多可以向前跳跃 k 步,但不能跳出数组边界。也就是说,从当前下标 i,你可以跳到区间 [i+1, min(n-1, i+k)] 中的任意位置。

你的目标是跳到数组的最后一个位置(下标为 n-1),并且你获得的分数是你经过的所有数字的和。

请返回你能获得的最大得分。


解题分析

这道题本质上是一个动态规划问题,我们要在满足跳跃范围的条件下,找到一条路径使得经过的元素和最大。

  • 状态定义
    dp[i] 表示跳到位置 i 时能获得的最大分数。
  • 初始状态
    dp[0] = nums[0],因为起点就是数组的第一个元素。

状态转移
i 的前面 k 个位置中选一个能让 dp[j] 最大的跳跃过来,再加上 nums[i]
即:

  • dp[i]=max⁡j∈[i−k,i−1]dp[j]+nums[i]dp[i] = \max_{j \in [i-k, i-1]} dp[j] + nums[i]
  • 目标
    求出 dp[n-1],即跳到数组最后一个位置能获得的最大得分。

解题方法

1. 朴素动态规划

直接按照状态转移方程计算:

for i in range(1, n):
    dp[i] = max(dp[j] for j in range(i-k, i)) + nums[i]
  • 时间复杂度
    每个 i 都要查询 k 个状态,整体复杂度为 O(n×k)O(n \times k)。
  • 缺点
    nk 都很大时,效率低下,无法通过大规模测试。

2. 单调队列优化

注意到在计算 dp[i] 时,我们只关心区间 [i-k, i-1]dp[j] 的最大值。

  • 使用一个双端队列 dq,存储下标,保证 dp[dq[0]] 是当前窗口最大值。
  • 窗口向右滑动时,维护队列中元素的有效性(排除超过跳跃范围的下标)。
  • 维护队列单调递减,使得队头永远是最大值的索引。
代码实现
from collections import deque

class Solution:
    def maxResult(self, nums: List[int], k: int) -> int:
        n = len(nums)
        dp = [0] * n
        dp[0] = nums[0]
        
        dq = deque([0])  # 存放索引,保持dp值单调递减
        
        for i in range(1, n):
            # 弹出不再窗口范围内的索引
            while dq and dq[0] < i - k:
                dq.popleft()
            
            # dp[i]由窗口最大dp值加nums[i]转移
            dp[i] = dp[dq[0]] + nums[i]
            
            # 维护单调递减队列
            while dq and dp[dq[-1]] <= dp[i]:
                dq.pop()
            
            dq.append(i)
        
        return dp[-1]

复杂度分析与对比

方法

时间复杂度

空间复杂度

适用情况

朴素动态规划

O(n×k)O(n \times k)

O(n)O(n)

kk 和 nn 较小

单调队列优化

O(n)O(n)

O(n)O(n)

适用于大规模数据,效率高


示例说明

假设输入:

nums = [1, -1, -2, 4, -7, 3]
k = 2

执行过程:

  • 初始化:dp[0] = 1
  • 计算 dp[1]:从 dp[0] 跳,最大是 1 + (-1) = 0
  • 计算 dp[2]:从 dp[0], dp[1] 中选最大,max(1,0) + (-2) = -1
  • 计算 dp[3]:从 dp[1], dp[2] 中选最大,max(0, -1) + 4 = 4
  • 计算 dp[4]:从 dp[2], dp[3] 中选最大,max(-1, 4) + (-7) = -3
  • 计算 dp[5]:从 dp[3], dp[4] 中选最大,max(4, -3) + 3 = 7

最终结果是 dp[5] = 7


总结

  • 本题通过动态规划解决跳跃路径最大和问题。
  • 直接动态规划时间复杂度高,采用单调队列优化窗口最大值查询使复杂度降至 O(n)O(n)。
  • 单调队列是处理滑动窗口最大值问题的经典技巧,能显著提升效率。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值