|
| 1 | +--- |
| 2 | +id: jump-game-II |
| 3 | +title: Jump Game II(LeetCode) |
| 4 | +sidebar_label: 0045-Jump-Game-II |
| 5 | +tags: |
| 6 | + - Array |
| 7 | + - Dynamic Programming |
| 8 | + - Greedy |
| 9 | +description: You are given a 0-indexed array of integers nums of length `n`. Return the minimum number of jumps to reach `nums[n - 1]`. |
| 10 | +sidebar_position: 45 |
| 11 | +--- |
| 12 | + |
| 13 | +## Problem Statement |
| 14 | + |
| 15 | +You are given a 0-indexed array of integers `nums` of length `n`. You are initially positioned at `nums[0]`. |
| 16 | + |
| 17 | +Each element `nums[i]` represents the maximum length of a forward jump from index `i`. In other words, if you are at `nums[i]`, you can jump to any `nums[i + j]` where: |
| 18 | + |
| 19 | +- `0 <= j <= nums[i]` and |
| 20 | +- `i + j < n` |
| 21 | +Return the minimum number of jumps to reach `nums[n - 1]`. The test cases are generated such that you can reach `nums[n - 1]`. |
| 22 | + |
| 23 | +### Examples |
| 24 | + |
| 25 | +**Example 1:** |
| 26 | + |
| 27 | +```plaintext |
| 28 | +Input: nums = [2,3,1,1,4] |
| 29 | +Output: 2 |
| 30 | +Explanation: The minimum number of jumps to reach the last index is 2. Jump 1 step from index 0 to 1, then 3 steps to the last index. |
| 31 | +``` |
| 32 | + |
| 33 | +**Example 2:** |
| 34 | + |
| 35 | +```plaintext |
| 36 | +Input: nums = [2,3,0,1,4] |
| 37 | +Output: 2 |
| 38 | +``` |
| 39 | + |
| 40 | +### Constraints |
| 41 | + |
| 42 | +- `1 <= nums.length <= 104` |
| 43 | +- `0 <= nums[i] <= 1000` |
| 44 | +- It's guaranteed that you can reach `nums[n - 1]`. |
| 45 | + |
| 46 | +## Solution |
| 47 | + |
| 48 | +In this problem, we aim to find the minimum number of jumps required to reach the end of the array, starting from the first element. We explore three main approaches: Recursive Dynamic Programming with |
| 49 | +Memoization, Iterative Dynamic Programming with Tabulation, and a Greedy BFS approach. |
| 50 | + |
| 51 | +### Approach 1: Recursive Dynamic Programming (Memoization) |
| 52 | +Concept: Store the solutions for each position to avoid redundant calculations. |
| 53 | + |
| 54 | +#### Algorithm |
| 55 | + |
| 56 | +1. Initialize `dp` array with a large value to indicate uncomputed positions. |
| 57 | +2. Call the recursive function `solve` starting from position 0. |
| 58 | +3. In `solve`: |
| 59 | +* If the position is at or beyond the end, return 0. |
| 60 | +* If `dp[pos]` is already computed, return its value. |
| 61 | +* Explore all possible jumps from the current position. |
| 62 | +* Store and return the minimum jumps required. |
| 63 | + |
| 64 | +#### Implementation |
| 65 | + |
| 66 | +```C++ |
| 67 | +int jump(vector<int>& nums) { |
| 68 | + vector<int> dp(size(nums), 10001); |
| 69 | + return solve(nums, dp, 0); |
| 70 | +} |
| 71 | + |
| 72 | +int solve(vector<int>& nums, vector<int>& dp, int pos) { |
| 73 | + if(pos >= size(nums) - 1) return 0; |
| 74 | + if(dp[pos] != 10001) return dp[pos]; |
| 75 | + for(int j = 1; j <= nums[pos]; j++) |
| 76 | + dp[pos] = min(dp[pos], 1 + solve(nums, dp, pos + j)); |
| 77 | + return dp[pos]; |
| 78 | +} |
| 79 | +``` |
| 80 | +
|
| 81 | +### Complexity Analysis |
| 82 | +
|
| 83 | +- **Time complexity**: O(N^2) |
| 84 | +- **Space complexity**: O(N) |
| 85 | +
|
| 86 | +### Approach 2: Iterative Dynamic Programming (Tabulation) |
| 87 | +
|
| 88 | +Concept: Start from the last index and iteratively compute the minimum jumps required for each position. |
| 89 | +
|
| 90 | +#### Algorithm |
| 91 | +
|
| 92 | +1. Initialize `dp` array with large values and set `dp[n-1]` to 0. |
| 93 | +2. Iterate from the second last index to the start. |
| 94 | +3. For each index, explore all possible jumps and store the minimum jumps required. |
| 95 | + |
| 96 | +#### Implementation |
| 97 | +
|
| 98 | +```C++ |
| 99 | +int jump(vector<int>& nums) { |
| 100 | + int n = size(nums); |
| 101 | + vector<int> dp(n, 10001); |
| 102 | + dp[n - 1] = 0; |
| 103 | + for(int i = n - 2; i >= 0; i--) |
| 104 | + for(int jumpLen = 1; jumpLen <= nums[i]; jumpLen++) |
| 105 | + dp[i] = min(dp[i], 1 + dp[min(n - 1, i + jumpLen)]); |
| 106 | + return dp[0]; |
| 107 | +} |
| 108 | +``` |
| 109 | + |
| 110 | +### Complexity Analysis |
| 111 | + |
| 112 | +- **Time complexity**: O(N^2) |
| 113 | +- **Space complexity**: O(N) |
| 114 | + |
| 115 | +### Approach 3: Greedy BFS |
| 116 | + |
| 117 | +Concept: Use two pointers to track the furthest reachable position |
| 118 | +and the currently furthest reached position. Update the jump count when moving to a new level. |
| 119 | + |
| 120 | +#### Algorithm |
| 121 | + |
| 122 | +1. Initialize `maxReachable`, `lastJumpedPos`, and `jumps`. |
| 123 | +2. Iterate over the array until the lastJumpedPos reaches or exceeds the last index. |
| 124 | +3. Update `maxReachable` with the furthest position reachable from the current index. |
| 125 | +4. When `i` equals `lastJumpedPos`, move to `maxReachable` and increment jumps. |
| 126 | + |
| 127 | +#### Implementation |
| 128 | + |
| 129 | +```C++ |
| 130 | +int jump(vector<int>& nums) { |
| 131 | + int n = size(nums), i = 0, maxReachable = 0, lastJumpedPos = 0, jumps = 0; |
| 132 | + while(lastJumpedPos < n - 1) { |
| 133 | + maxReachable = max(maxReachable, i + nums[i]); |
| 134 | + if(i == lastJumpedPos) { |
| 135 | + lastJumpedPos = maxReachable; |
| 136 | + jumps++; |
| 137 | + } |
| 138 | + i++; |
| 139 | + } |
| 140 | + return jumps; |
| 141 | +} |
| 142 | +``` |
| 143 | +
|
| 144 | +### Complexity Analysis |
| 145 | +
|
| 146 | +- **Time complexity**: O(N) |
| 147 | +- **Space complexity**: O(1) |
| 148 | +
|
| 149 | +### Conclusion |
| 150 | +
|
| 151 | +1. Recursive DP with Memoization: Efficiently avoids redundant calculations but has higher time complexity. |
| 152 | +2. Iterative DP with Tabulation: Iteratively solves for each position but has quadratic time complexity. |
| 153 | +3. Greedy BFS: Provides the most optimal solution with linear time complexity and constant space, making it the best approach for this problem. |
0 commit comments