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] }