Algorithm/src/main/java/All/MaxResult.java
2025-09-27 12:25:49 +08:00

66 lines
2.2 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package All;
import java.util.Deque;
import java.util.LinkedList;
/**
* 题目: 1696. 跳跃游戏 VI
* 描述:给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。
* 一开始你在下标 0 处。每一步,你最多可以往前跳 k 步,但你不能跳出数组的边界。也就是说,你可以从下标 i 跳到 [i + 1 min(n - 1, i + k)] 包含 两个端点的任意位置。
* 你的目标是到达数组最后一个位置(下标为 n - 1 ),你的 得分 为经过的所有数字之和。
* 请你返回你能得到的 最大得分 。
示例 1
输入nums = [1,-1,-2,4,-7,3], k = 2
输出7
解释:你可以选择子序列 [1,-1,4,3] (上面加粗的数字),和为 7 。
* 链接https://leetcode.cn/problems/jump-game-vi/
*/
//不会做
public class MaxResult {
//超时
public int maxResult2(int[] nums, int k) {
int n = nums.length;
int[] f = new int[n];
f[0] = nums[0];
for (int i = 1; i < n; i++) {
int mx = Integer.MIN_VALUE;
for (int j = Math.max(i - k, 0); j < i; j++) {
mx = Math.max(mx, f[j]);
}
f[i] = mx + nums[i];
}
return f[n - 1];
}
/*
dp[i] = max(dp[j]) + nums[i],其中 j ∈ [i - k, i - 1]。
用一个双端队列存放“候选下标”,保持队列里的 dp 值是单调递减的,这样队首永远是最大值。
*/
public int maxResult(int[] nums, int k) {
int n = nums.length;
int[] dp = new int[n];
dp[0] = nums[0];
Deque<Integer> deque = new LinkedList<>();
deque.offer(0); // 队列存的是下标
for (int i = 1; i < n; i++) {
// 队首如果滑出窗口 [i-k, i-1] 就移除
while (!deque.isEmpty() && deque.peek() < i - k) {
deque.poll();
}
// 队首就是窗口内 dp 最大值的下标
dp[i] = dp[deque.peek()] + nums[i];
// 保持队列单调递减:把比当前 dp[i] 小的值都踢掉
while (!deque.isEmpty() && dp[i] >= dp[deque.peekLast()]) {
deque.pollLast();
}
deque.offer(i);
}
return dp[n - 1];
}
}