Problem Statement

Jump Game II

You have an array of numbers called nums. You start standing on the first number (the one at index 0). The number you are standing on tells you the most steps you are allowed to jump forward from that spot. So if the number is 3, you can jump 1, 2, or 3 spots ahead. Your goal is to reach the very last spot in the array using as few jumps as possible. The problem promises the last spot is always reachable, so you never have to worry about getting stuck. We solve this with a greedy approach. Greedy means at each decision we grab the best option in front of us right now, without trying every possible path. Here the best option is simple: from where we can currently land, always keep track of the spot that reaches the farthest, and only spend a jump when we are forced to.

mediumGreedyArrayGreedyTime: O(n) · Space: O(1)

Signals to notice

minimum jumps to reach endeach position has a jump rangecount steps not reachability

Brute force first

BFS from index 0, each position enqueues all reachable positions. Processes every reachable index. It is a fair place to begin because it matches the surface of the question, yet it does not capture the deeper structure that makes the problem simpler.

The key insight

Greedy BFS: track the farthest reachable index and the end of the current 'level.' When you pass the current level's end, increment jumps and update the level boundary. Once you hold onto the right piece of information from moment to moment, the problem feels less like trial and error and more like following a shape that was there all along.

Trace it on nums=[2,3,1,1,4]

init: jumps=0, cur_end=0, farthest=0 (loop i runs 0..3)
i=0: farthest=max(0,0+2)=2; i==cur_end(0) -> jumps=1, cur_end=2
i=1: farthest=max(2,1+3)=4; i(1)!=cur_end(2) -> no jump
i=2: farthest=max(4,2+1)=4; i==cur_end(2) -> jumps=2, cur_end=4
i=3: farthest=max(4,3+1)=4; i(3)!=cur_end(4) -> no jump
loop ends -> return jumps=2

What must stay true

Each 'jump' covers all positions reachable from the current level. The farthest position reachable from this level becomes the boundary of the next level. You never need to revisit positions. If that remains true after every update, the rest of the reasoning has a stable place to stand.

Shape of the loop

jumps = cur_end = farthest = 0
for i in 0 .. n-2:
    farthest = max(farthest, i + nums[i])
    if i == cur_end:          # crossed this level's boundary
        jumps += 1
        cur_end = farthest    # next level reaches this far
return jumps

Pseudocode only — the full worked solution lives in the Solution tab.

Easy way to go wrong

Using actual BFS with a queue — the greedy approach achieves the same result without a queue by tracking the level boundary implicitly. When the code becomes mechanical before the idea is clear, small edge cases start breaking the whole story.

Greedy Pattern