Jump Game VI

medium dp monotonic deque

Problem

You stand on index 0 of an integer array nums and want to reach the last index. From index i you may hop forward to any index from i+1 up to min(n−1, i+k). Every index you land on (including index 0) adds nums[index] to your score — values can be negative, so greedy hopping can hurt.

Return the maximum total score with which you can reach index n−1.

Inputnums = [1,-1,-2,4,-7,3], k = 2
Output7
Best path visits 1 → -1 → 4 → 3, scoring 1 + (-1) + 4 + 3 = 7.

def max_result(nums, k):
    from collections import deque
    n = len(nums)
    dp = [0] * n
    dp[0] = nums[0]
    dq = deque([0])                # indices; dp values decreasing
    for i in range(1, n):
        while dq[0] < i - k:       # front fell out of the window
            dq.popleft()
        dp[i] = nums[i] + dp[dq[0]]
        while dq and dp[dq[-1]] <= dp[i]:
            dq.pop()               # smaller scores can never win
        dq.append(i)
    return dp[n - 1]
function maxResult(nums, k) {
  const n = nums.length;
  const dp = new Array(n).fill(0);
  dp[0] = nums[0];
  const dq = [0]; // indices; dp values decreasing
  for (let i = 1; i < n; i++) {
    while (dq[0] < i - k) dq.shift(); // front fell out of the window
    dp[i] = nums[i] + dp[dq[0]];
    while (dq.length && dp[dq[dq.length - 1]] <= dp[i]) dq.pop();
    dq.push(i);
  }
  return dp[n - 1];
}
int maxResult(int[] nums, int k) {
    int n = nums.length;
    int[] dp = new int[n];
    dp[0] = nums[0];
    Deque<Integer> dq = new ArrayDeque<>(); // indices; dp decreasing
    dq.addLast(0);
    for (int i = 1; i < n; i++) {
        while (dq.peekFirst() < i - k) dq.pollFirst(); // out of window
        dp[i] = nums[i] + dp[dq.peekFirst()];
        while (!dq.isEmpty() && dp[dq.peekLast()] <= dp[i]) dq.pollLast();
        dq.addLast(i);
    }
    return dp[n - 1];
}
int maxResult(vector<int>& nums, int k) {
    int n = nums.size();
    vector<int> dp(n, 0);
    dp[0] = nums[0];
    deque<int> dq{0}; // indices; dp values decreasing
    for (int i = 1; i < n; i++) {
        while (dq.front() < i - k) dq.pop_front(); // out of window
        dp[i] = nums[i] + dp[dq.front()];
        while (!dq.empty() && dp[dq.back()] <= dp[i]) dq.pop_back();
        dq.push_back(i);
    }
    return dp[n - 1];
}
Time: O(n) Space: O(n)