跳跃游戏 VI
难度:
标签:
题目描述
代码结果
运行时间: 88 ms, 内存: 27.5 MB
/*
* 思路:
* 使用Java Stream无法直接实现此算法,因为它涉及到动态规划和双端队列的操作。
* 但是我们可以使用Java Stream的api来简化数组的初始化等步骤。
*/
import java.util.*;
import java.util.stream.*;
public class MaxScoreStream {
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.add(0);
for (int i = 1; i < n; i++) {
dp[i] = nums[i] + dp[deque.peekFirst()];
while (!deque.isEmpty() && dp[i] >= dp[deque.peekLast()]) {
deque.pollLast();
}
deque.addLast(i);
if (i - deque.peekFirst() >= k) {
deque.pollFirst();
}
}
return dp[n - 1];
}
}
解释
方法:
这道题的核心思路是使用动态规划(DP)结合单调队列优化。DP数组表示到达每个位置i的最大得分。为了避免重复计算每个位置最大得分时所有可能的前驱位置的得分,我们使用一个单调队列来优化这个过程。队列中存储的是索引,且保证队头是最大的DP值的索引。遍历数组时,每到一个正数或者数组最后一个元素,检查是否能直接从上一个正数位置跳到当前位置。如果不能,就用单调队列来计算从上一个正数位置到当前位置的最大得分,更新中间的DP值,并更新队列以保持单调递减。总的来说,此题解通过减少重复计算并快速访问当前最大得分,从而降低了时间复杂度。
时间复杂度:
O(n)
空间复杂度:
O(k)
代码细节讲解
🦆
题解中提到当`k=1`时直接返回整个数组的和,这种方法是否忽略了数组中可能存在的负数对总和的影响?
▷🦆
单调队列的使用在这种情况下如何确保队头始终是最大的DP值的索引?能否详细解释这一过程?
▷🦆
题解中提到,如果当前数字是非负数或者是数组的最后一个元素时,会检查是否能直接从上一个非负数位置跳到当前位置。这里的逻辑是否意味着在两个非负数之间的负数会被忽略?这样做的原因是什么?
▷