Welcome to Subscribe On Youtube

Formatted question description: https://leetcode.ca/all/1696.html

1696. Jump Game VI (Medium)

You are given a 0-indexed integer array nums and an integer k.

You are initially standing at index 0. In one move, you can jump at most k steps forward without going outside the boundaries of the array. That is, you can jump from index i to any index in the range [i + 1, min(n - 1, i + k)] inclusive.

You want to reach the last index of the array (index n - 1). Your score is the sum of all nums[j] for each index j you visited in the array.

Return the maximum score you can get.

 

Example 1:

Input: nums = [1,-1,-2,4,-7,3], k = 2
Output: 7
Explanation: You can choose your jumps forming the subsequence [1,-1,4,3] (underlined above). The sum is 7.

Example 2:

Input: nums = [10,-5,-2,4,0,3], k = 3
Output: 17
Explanation: You can choose your jumps forming the subsequence [10,4,3] (underlined above). The sum is 17.

Example 3:

Input: nums = [1,-5,-20,4,-1,3,-6,-3], k = 2
Output: 0

 

Constraints:

  •  1 <= nums.length, k <= 105
  • -104 <= nums[i] <= 104

Related Topics:
Dequeue

Similar Questions:

Solution 1. Mono-queue + DP

For A[i], we can choose the greatest value we can get among A[j] where max(0, i - k) <= j < i.

So we can memoize the results using a dp array where dp[i] is the maximum score we can get jumping from A[0] to A[i].

dp[i] = A[i] + max( dp[j] | max(0, i - k) <= j < i )
dp[0] = A[0]

For the part calculating max value, doing it in a brute force manner will take O(K) time and result in TLE. We can use mono-queue to reduce the time complexity to amortized O(1).

Since we are looking for the maximum value in a range, we can use a decreasing mono-queue.

// OJ: https://leetcode.com/problems/jump-game-vi/
// Time: O(N)
// Space: O(N)
class Solution {
public:
    int maxResult(vector<int>& A, int k) {
        int N = A.size();
        vector<long> dp(N, INT_MIN);
        dp[0] = A[0];
        deque<int> q;
        q.push_back(0);
        for (int i = 1; i < N; ++i) {
            dp[i] = A[i] + dp[q.front()]; // dp[q.front()] is the maximum dp value in range.
            if (q.size() && q.front() <= i - k) q.pop_front(); // pop the front element because it goes out of range.
            while (q.size() && dp[q.back()] <= dp[i]) q.pop_back(); // pop the elements that are smaller than or equal to dp[i] out of the queue.
            q.push_back(i);
        }
        return dp[N - 1];
    }
};
  • class Solution {
        public int maxResult(int[] nums, int k) {
            int length = nums.length;
            int[] dp = new int[length];
            dp[0] = nums[0];
            int max = nums[0];
            int firstMaxIndex = Math.min(length - 1, k);
            for (int i = 1; i <= firstMaxIndex; i++) {
                dp[i] = max + nums[i];
                max = Math.max(max, dp[i]);
            }
            Deque<Integer> deque = new LinkedList<Integer>();
            for (int i = 1; i <= firstMaxIndex; i++) {
                int sum = dp[i];
                while (!deque.isEmpty() && dp[deque.getLast()] < sum)
                    deque.removeLast();
                deque.offerLast(i);
            }
            for (int i = firstMaxIndex + 1; i < length; i++) {
                if (!deque.isEmpty() && deque.getFirst() == i - k - 1)
                    deque.pollFirst();
                int num = nums[i];
                int sum = dp[deque.peekFirst()] + num;
                dp[i] = sum;
                while (!deque.isEmpty() && dp[deque.peekLast()] < sum)
                    deque.pollLast();
                deque.offerLast(i);
            }
            return dp[length - 1];
        }
    }
    
    ############
    
    class Solution {
        public int maxResult(int[] nums, int k) {
            int n = nums.length;
            int[] f = new int[n];
            Deque<Integer> q = new ArrayDeque<>();
            q.offer(0);
            for (int i = 0; i < n; ++i) {
                if (i - q.peekFirst() > k) {
                    q.pollFirst();
                }
                f[i] = nums[i] + f[q.peekFirst()];
                while (!q.isEmpty() && f[q.peekLast()] <= f[i]) {
                    q.pollLast();
                }
                q.offerLast(i);
            }
            return f[n - 1];
        }
    }
    
  • // OJ: https://leetcode.com/problems/jump-game-vi/
    // Time: O(N)
    // Space: O(N)
    class Solution {
    public:
        int maxResult(vector<int>& A, int k) {
            int N = A.size();
            vector<int> dp(N);
            dp[0] = A[0];
            deque<int> q{0};
            for (int i = 1; i < N; ++i) {
                if (q.front() < i - k) q.pop_front(); // pop the front element if it goes out of range
                dp[i] = A[i] + dp[q.front()]; // dp[q.front()] is the maximum dp value in range.
                while (q.size() && dp[q.back()] <= dp[i]) q.pop_back(); // pop the elements that are smaller than or equal to dp[i] out of the queue.
                q.push_back(i);
            }
            return dp[N - 1];
        }
    };
    
  • class Solution:
        def maxResult(self, nums: List[int], k: int) -> int:
            n = len(nums)
            f = [0] * n
            q = deque([0])
            for i in range(n):
                if i - q[0] > k:
                    q.popleft()
                f[i] = nums[i] + f[q[0]]
                while q and f[q[-1]] <= f[i]:
                    q.pop()
                q.append(i)
            return f[-1]
    
    ############
    
    # 1696. Jump Game VI
    # https://leetcode.com/problems/jump-game-vi/
    
    class Solution:
        def maxResult(self, nums: List[int], k: int) -> int:
            n = len(nums)
            curr = 0
            deq = collections.deque()
            
            for i in range(n-1,-1,-1):
                curr = nums[i] + (nums[deq[0]] if deq else 0)
                
                while (deq and curr > nums[deq[-1]]):
                    deq.pop()
                
                deq.append(i)
                
                if deq[0] >= (i + k):
                    deq.popleft()
                
                nums[i] = curr
            
            return curr
    
  • func maxResult(nums []int, k int) int {
    	n := len(nums)
    	f := make([]int, n)
    	q := []int{0}
    	for i, v := range nums {
    		if i-q[0] > k {
    			q = q[1:]
    		}
    		f[i] = v + f[q[0]]
    		for len(q) > 0 && f[q[len(q)-1]] <= f[i] {
    			q = q[:len(q)-1]
    		}
    		q = append(q, i)
    	}
    	return f[n-1]
    }
    

All Problems

All Solutions