Jump Game VI
update Jun 9 2021

Basic Idea
基本思路就是DP,每次更新当前最优的最大score sum,看之前K个dp数组中的最大值,取最大的来更新当前的dp[i]. 而问题在于当k接近N的时候时间复杂度可能会变成 N^2
,所以我们需要对求dp数组中前面K个元素最大值进行优化。我们有如下两种思路
单调双端队列: 用这种方法我们可以用平均
O(1)
的时间完成更新和求当前最大,需要注意的是 Deque 中存的其实是index而不是真实的score sum的值,这样在左边移除的时候才能操作。另外注意因为我们需要维持的是最大值,所以我们需要一个递减的单调队列。PriorityQueue: 一开始没有想到这种方法,因为 heap 的remove操作是
O(N)
的,但是实际上类似于在 Dijkstra 中,我们可以做lazy deletion,当 heap 给我们的最大值的index超出了当前 i 左边 k 个的边界我们就忽略它,再从heap中取下一个,这样时间复杂度最多是O(NlogN)
Java Code:
单调双端队列解法
class Solution {
public int maxResult(int[] nums, int k) {
int[] dp = new int[nums.length];
dp[0] = nums[0];
// 单调递减队列,维持最大值的index
Deque<Integer> mDeque = new ArrayDeque<>();
mDeque.offerFirst(0);
for (int i = 1; i < dp.length; ++i) {
int maxIndex = mDeque.peekLast();
dp[i] = dp[maxIndex] + nums[i];
while (!mDeque.isEmpty() && dp[mDeque.peekFirst()] < dp[i]) {
mDeque.pollFirst();
}
mDeque.offerFirst(i);
if (i - k == mDeque.peekLast()) {
mDeque.pollLast();
}
}
return dp[dp.length - 1];
}
}
Last updated