Welcome to Subscribe On Youtube
Question
Formatted question description: https://leetcode.ca/all/45.html
You are given a 0-indexed array of integers nums
of length n
. You are initially positioned at nums[0]
.
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:
0 <= j <= nums[i]
andi + j < n
Return the minimum number of jumps to reach nums[n - 1]
. The test cases are generated such that you can reach nums[n - 1]
.
Example 1:
Input: nums = [2,3,1,1,4] Output: 2 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.
Example 2:
Input: nums = [2,3,0,1,4] Output: 2
Constraints:
1 <= nums.length <= 104
0 <= nums[i] <= 1000
- It's guaranteed that you can reach
nums[n - 1]
.
Algorithm
To solve this problem, we can use the Greedy
algorithm. The idea is to determine the farthest range that can be reached from the current position. We need to keep track of two variables, cur
and pre
, which represent the farthest position that can be reached from the current position and the farthest position that can be reached from the previous position, respectively.
Starting from the first position, we traverse all the positions that can be reached by the current jump. We then predict the farthest distance that can be jumped in the next step according to the jump force at that position and update cur
to be the maximum of its current value and i + A[i]
.
If the current position i
is less than or equal to pre
, it means that it is still within the range that the previous jump can reach. Therefore, we can update cur
as described above. If cur
is still less than or equal to i
, it means that we cannot go any further, and we should return -1.
If cur
reaches the last position, we can return the number of steps used so far, which is the minimum number of steps required to reach the end. Otherwise, we update pre
to be the same as cur
and repeat the process until we reach the end or determine that it cannot be reached.
Therefore, the time complexity of this algorithm is O(n), where n is the length of the input array, and the space complexity is O(1), as we only need to store two variables.
Code
Java
This one is easier to understand, with the break;
check
-
public class Solution { public int jump(int[] A) { int jumps = 0, curEnd = 0, curFarthest = 0; for (int i = 0; i < A.length - 1; i++) { // @note: i < Len - 1. 也就是停在倒数第二个 curFarthest = Math.max(curFarthest, i + A[i]); if (i == curEnd) { jumps++; curEnd = curFarthest; if (curEnd >= A.length - 1) { break; } } } return jumps; } } public class Jump_Game_II { class Solution { public int jump(int[] nums) { if (nums == null || nums.length == 0) { return 0; } int left = 0; // last jump reaching to int right = 0; // current jump reaching to int count = 0; for (int i = 0; i < nums.length - 1; i++) { // @note: i < Len - 1. 也就是停在倒数第二个 right = Math.max(right, i + nums[i]); if (i == left) { // reaching furthest of last jump count++; left = right; if (curEnd >= A.length - 1) { break; } } } return count; } } } ############ class Solution { public int jump(int[] nums) { int end = 0; int mx = 0; int steps = 0; for (int i = 0; i < nums.length - 1; ++i) { mx = Math.max(mx, i + nums[i]); if (i == end) { end = mx; ++steps; } } return steps; } }
-
// OJ: https://leetcode.com/problems/jump-game-ii/ // Time: O(N^2) // Space: O(N) class Solution { public: int jump(vector<int>& A) { int N = A.size(); vector<int> dp(N, INT_MAX); dp[0] = 0; for (int i = 0; i < N; ++i) { for (int j = 1; j <= A[i] && i + j < N; ++j) { dp[i + j] = min(dp[i + j], 1 + dp[i]); } } return dp[N - 1]; } };
-
class Solution: def jump(self, nums: List[int]) -> int: current_reach = next_reach = steps = 0 # stop at 2nd-to-last, not the last index. because, eg. nums=[1,0] or nums=[0,0], just check the 2nd-to-last then we can decide if able to reach end for i, num in enumerate(nums[:-1]): next_reach = max(next_reach, i + num) if i == current_reach: current_reach = next_reach steps += 1 # in question, guarenteed can reach end. or else need more check return steps ############ class Solution(object): def jump(self, nums): """ :type nums: List[int] :rtype: int """ pos = 0 ans = 0 bound = len(nums) while pos < len(nums) - 1: dis = nums[pos] farthest = posToFarthest = 0 for i in range(pos + 1, min(pos + dis + 1, bound)): canReach = i + nums[i] if i == len(nums) - 1: return ans + 1 if canReach > farthest: farthest = canReach posToFarthest = i ans += 1 pos = posToFarthest return ans
-
func jump(nums []int) int { mx, steps, end := 0, 0, 0 for i := 0; i < len(nums)-1; i++ { mx = max(mx, i+nums[i]) if i == end { end = mx steps++ } } return steps } func max(a, b int) int { if a > b { return a } return b }
-
public class Solution { public int Jump(int[] nums) { int end = 0; int mx = 0; int steps = 0; for (int i = 0; i < nums.Length - 1; ++i) { mx = Math.Max(mx, i + nums[i]); if (i == end) { end = mx; ++steps; } } return steps; } }
-
impl Solution { pub fn jump(nums: Vec<i32>) -> i32 { let n = nums.len(); let mut dp = vec![i32::MAX; n]; dp[0] = 0; for i in 0..n - 1 { for j in 1..=nums[i] as usize { if i + j >= n { break; } dp[i + j] = dp[i + j].min(dp[i] + 1); } } dp[n - 1] } }
-
function jump(nums: number[]): number { let ans = 0; let mx = 0; let last = 0; for (let i = 0; i < nums.length - 1; ++i) { mx = Math.max(mx, i + nums[i]); if (last === i) { ++ans; last = mx; } } return ans; }