Skip to content

Jump Game II

Given an integer array nums where you are initially positioned at the array’s first index, and each element in the array represents your maximum jump length from that position, determine the minimum number of jumps you need to make to reach the last index.

You are guaranteed that you can always reach the last index.

InputOutputExplanation
[2, 3, 1, 1, 4]2Jump to index 1, then jump 3 steps to the last index.
[2, 3, 0, 6, 9, 1, 2]3Jump to index 1, then to index 3 or 4 (from either you can reach 6), then to index 6.
[10]0Already at the last index.
[1, 1, 1, 0]3Must jump once from each index because you can only jump 1 step at a time.
  • 1 <= nums.length <= 10^4
  • 0 <= nums[i] <= 1000
  • It is guaranteed that you can always reach nums.length - 1.
ApproachTimeSpaceKey InsightBest When
Greedy Min JumpsO(n)O(1)Always extend reach as far as possible before jumpingGeneral case — optimal and simple
Dynamic ProgrammingO(n²)O(n)Compute minimum jumps to each position, then look backInterview deep dive / illustrating DP pattern
  • Pick Greedy Min Jumps if you want the optimal, elegant solution that works in linear time.
  • Pick Dynamic Programming if you want to understand the foundational DP pattern (though it is slower).
Best For Speed
Greedy Min Jumps
O(n) time · O(1) space
Foundational Pattern
Dynamic Programming
O(n²) time · O(n) space
Section titled “Approach 1: Greedy Min Jumps (Recommended)”
★ Recommended

Maintain a current_end that represents the farthest index reachable with the current number of jumps. When you reach current_end, you must jump, and you extend your reach to farthest—the farthest index you saw while scanning up to current_end.

Key insight: You don’t decide where to jump to. Instead, you scan ahead to see how far you can go, then commit to jumping when you exhaust your current range.

⏱ Time O(n) Single pass 💾 Space O(1) Two pointers

Input: nums = [2, 3, 1, 1, 4]

Stepinums[i]Reach from icurrent_endfarthestAction
1020+2=202i==current_end → jump (jumps=1, current_end=2)
2131+3=424farthest updated to 4
3212+1=324i==current_end → jump (jumps=2, current_end=4)
4313+1=444current_end>=len-1 → done

Result: jumps = 2 ✓

Input: nums = [2, 3, 0, 6, 9, 1, 2]

Stepinums[i]Reach from icurrent_endfarthestAction
1020+2=202i==current_end → jump (jumps=1, current_end=2)
2131+3=424farthest updated to 4
3202+0=224i==current_end → jump (jumps=2, current_end=4)
4363+6=949farthest updated to 9
5494+9=13413current_end>=len-1 → done

Result: jumps = 2 ✓

Animated walkthrough

How the greedy min jumps solution counts jumps

Watch how current_end expands and farthest extends. When you reach current_end, you must jump and adopt farthest as your new range.

Step 1 of 7
Waiting to begin...
Array state
Memory / lookup state

function jumpGameIIGreedy(nums):
if len(nums) <= 1:
return 0
jumps = 0
current_end = 0 // End of range reachable with current jumps
farthest = 0 // Farthest index reachable so far
for i in range(len(nums) - 1):
farthest = max(farthest, i + nums[i])
if i == current_end:
jumps++
current_end = farthest
if current_end >= len(nums) - 1:
break
return jumps
jump_game_ii_greedy.py
from typing import List
def jump_game_ii_greedy(nums: List[int]) -> int:
"""
Greedy approach: track the farthest reachable index and jump count.
Intuition: We maintain the range [current_start, current_end] that can be reached
with the current number of jumps. When we exhaust this range, we increment jumps
and expand to [current_end + 1, farthest], which is reachable with one more jump.
Time Complexity: O(n) - single pass through array
Space Complexity: O(1) - only use constant extra space
"""
if len(nums) <= 1:
return 0
jumps = 0
current_end = 0 # End of range reachable with current number of jumps
farthest = 0 # Farthest index reachable so far
for i in range(len(nums) - 1): # No need to check the last index
# Update the farthest index we can reach
farthest = max(farthest, i + nums[i])
# If we've reached the end of current jump range, we must jump
if i == current_end:
jumps += 1
current_end = farthest
# Optimization: if we can reach the end, no need to continue
if current_end >= len(nums) - 1:
break
return jumps
# Test cases
print(jump_game_ii_greedy([2, 3, 1, 1, 4])) # 2 (0->1->4)
print(jump_game_ii_greedy([2, 3, 0, 6, 9, 1, 2])) # 3 (0->1->3/4->6)
print(jump_game_ii_greedy([10])) # 0 (already at end)
print(jump_game_ii_greedy([1, 1, 1, 0])) # 3 (must jump 1 step at a time)
🎯 Interview Favourite

Compute the minimum number of jumps needed to reach each index by looking back at all indices that can reach the current index, and taking the minimum.

For each index i, check all previous indices j where j + nums[j] >= i. Any such j can reach i in one jump. The minimum jumps to reach i is 1 + min(jumps to reach j).

⏱ Time O(n²) Nested loops 💾 Space O(n) DP array

Input: nums = [2, 3, 1, 1, 4]

ij ranges that reach imin(dp[j] + 1)dp[i]
00 (start)
1j=0: 0+2>=1 ✓dp[0]+1 = 11
2j=0: 0+2>=2 ✓dp[0]+1 = 11
3j=1: 1+3>=3 ✓dp[1]+1 = 22
4j=1: 1+3>=4 ✓dp[1]+1 = 22

Result: dp[4] = 2 ✓

function jumpGameIIDP(nums):
if len(nums) <= 1:
return 0
n = len(nums)
dp = [infinity] * n
dp[0] = 0
for i in range(1, n):
for j in range(i):
if j + nums[j] >= i:
dp[i] = min(dp[i], dp[j] + 1)
break
return dp[n - 1]
jump_game_ii_dp.py
from typing import List
def jump_game_ii_dp(nums: List[int]) -> int:
"""
Dynamic Programming approach: compute minimum jumps needed to reach each index.
Intuition: dp[i] = minimum number of jumps to reach index i.
For each index i, look back at all indices j where j + nums[j] >= i,
meaning from j we can reach i in one jump. Take the minimum jumps[j] + 1.
Time Complexity: O(n²) - for each index, we may check all previous indices
Space Complexity: O(n) - dp array
This approach is less efficient than greedy but illustrates the classic DP pattern.
"""
if len(nums) <= 1:
return 0
n = len(nums)
# dp[i] = minimum jumps needed to reach index i
dp = [float('inf')] * n
dp[0] = 0 # Start at index 0 with 0 jumps
for i in range(1, n):
# Check all previous indices to see which can reach i
for j in range(i):
if j + nums[j] >= i: # From index j, we can reach index i
dp[i] = min(dp[i], dp[j] + 1)
break # Optimization: since we want minimum, once we find a j that reaches i, we can stop
return dp[n - 1]
# Test cases
print(jump_game_ii_dp([2, 3, 1, 1, 4])) # 2
print(jump_game_ii_dp([2, 3, 0, 6, 9, 1, 2])) # 3
print(jump_game_ii_dp([10])) # 0
print(jump_game_ii_dp([1, 1, 1, 0])) # 3
✓ Simple

A third approach demonstrating an alternative technique for solving this problem. This implementation optimizes either time or space complexity compared to the previous approaches.

⏱ Time O(n) Optimized complexity 💾 Space O(1) Efficient space usage
function approach3():
// Implementation approach goes here
jump_game_ii_space_optimized.py
"""
Solution for Jump Game II
"""
def solve():
"""Implementation for approach 3 of Jump Game II"""
pass
if __name__ == "__main__":
print("Solution ready")