Algorithm

Jump Game

Greedy & Intervals Pattern

Jump Game

You are given an integer array nums. You start at index 0, and nums[i] is the maximum number of positions you may jump forward from index i — you may jump any distance from 0 up to nums[i]. Return true if you can reach the last index by some sequence of jumps, and false otherwise. A value of 0 means you cannot move forward from that index at all.

CONSTRAINTS
  • 1 ≤ nums.length ≤ 10⁴
  • 0 ≤ nums[i] ≤ 10⁵
  • You always start at index 0
  • From index i you may land on any index from i+1 up to i + nums[i], if it exists
EXAMPLE 1
Input: nums = [2, 3, 1, 1, 4]
Output: true
From index 0 a jump of 1 reaches index 1, and from there the value 3 reaches the final index directly. The frontier passes the end, so the answer is true.
EXAMPLE 2
Input: nums = [3, 2, 1, 0, 4]
Output: false
Every route lands on index 3, whose value 0 permits no forward move, and no earlier index reaches far enough to jump over it, so the last index is unreachable.
EXAMPLE 3
Input: nums = [0]
Output: true
The start is already the last index, so no jump is needed even though its value is 0.
EXAMPLE 4
Input: nums = [2, 0, 0]
Output: true
The value 2 at index 0 leaps directly over both zeros to the last index.
EXAMPLE 5
Input: nums = [1, 0, 1]
Output: false
Index 0 reaches only index 1, whose value 0 stops all forward motion, so index 2 can never be reached.
Do I have to jump exactly nums[i], or at most nums[i]?
At most. From index i you may land on any index from i+1 up to i + nums[i], so you have full freedom to jump short. This flexibility is exactly why the reachable set is a solid prefix with no gaps.
Does the array contain only non-negative values?
Yes, jump lengths are zero or positive, so you can only move forward or stall. A zero is the only thing that can trap you, and only if nothing earlier reaches past it.
What if the array has a single element?
You are already at the last index, so the answer is true regardless of that element's value. The loop handles this because the end condition is checked from the start.
Do I need to return the actual jumps or the number of jumps?
No, only whether the end is reachable. Counting the minimum jumps is the harder follow-up, Jump Game II, which extends the same frontier idea.
What is being asked

Each index gives you a maximum jump length. From index i with value 3, you may step to i+1, i+2, or i+3 — your choice. Can you, by some series of such steps, land on the final index? A single 0 is a wall you cannot step over from where you stand, but you can often jump over it if you build up enough reach earlier.

We only want a yes/no reachability answer, not the number of jumps or the path. That "yes/no" is a hint: reachability problems often collapse to tracking a single number.

The exponential temptation

The literal reading invites recursion: from each index, try every jump length and see if any leads home.

python
def can_reach(i, nums):
    if i >= len(nums) - 1:
        return True
    for jump in range(1, nums[i] + 1):
        if can_reach(i + jump, nums):
            return True
    return False

This branches enormously — each index fans out into many, and the same indices get re-explored down countless paths, giving exponential time. Memoising it would bring it down to O(N²), the DP version, but there is a property here that makes even that unnecessary.

The reframe: forget paths, track reach

The insight is to stop asking "which sequence of jumps?" and ask only: what is the furthest index I could possibly be standing on by now? Call it reach.

Walk left to right. At each index i, first check whether i is even reachable — that is, whether i <= reach. If it is not, then no earlier index could launch you as far as i, so there is a gap you cannot cross, and the answer is false. If i is reachable, then from i you can extend your frontier to i + nums[i], so update reach to the larger of its current value and i + nums[i]. The moment reach reaches or passes the last index, the answer is true.

Why is it safe to collapse all those paths into one number? Because reachability is downward closed: if you can reach index i, you can reach every index between your start and i too (just jump shorter). So the entire set of currently-reachable indices is always a solid prefix 0..reach with no holes, and a single number describes it completely. That is the property the yes/no phrasing was hinting at.

python
def can_jump(nums):
    reach = 0
    for i in range(len(nums)):
        if i > reach:            # this index is unreachable: a gap we cannot cross
            return False
        reach = max(reach, i + nums[i])
        if reach >= len(nums) - 1:
            return True
    return True

One pass, O(N) time, O(1) space. This is a greedy: at every step we make the locally maximal extension of the frontier and never reconsider, and it is safe precisely because a wider frontier can never hurt a reachability question.

Worked Example:[2, 3, 1, 1, 4]
- i=0: 0 ≤ reach(0), fine. reach = max(0, 0+2) = 2.
- i=1: 1 ≤ 2, fine. reach = max(2, 1+3) = 4. That is the last index → true.

And the failing case, [3, 2, 1, 0, 4]:
- i=0: reach = max(0, 3) = 3.
- i=1: 1 ≤ 3. reach = max(3, 1+2) = 3.
- i=2: 2 ≤ 3. reach = max(3, 2+1) = 3.
- i=3: 3 ≤ 3. reach = max(3, 3+0) = 3. The frontier is stuck at 3.
- i=4: 4 > reach(3) → false. The 0 at index 3 is a wall, and nothing before it reached far enough to leap over.

The reflex to keep

Two transferable ideas.

When a problem asks whether something is reachable, look for a single frontier value to carry forward instead of enumerating paths. It works whenever reachability is monotonic — being able to reach far implies being able to reach everything nearer. That "solid prefix" structure is what turns an exponential search into one greedy pass.

A wider frontier is always at least as good, so greedily maximising it at each step is safe with no exchange argument gymnastics needed — the monotonicity is the argument. Contrast that with the coin problem, where more of a coin was not automatically better; here more reach genuinely cannot hurt.

The natural follow-up, Jump Game II, asks for the minimum number of jumps rather than mere reachability. That needs a little more — you track the current jump's frontier and the best frontier reachable within it, incrementing a counter each time you are forced to extend — but it is the same "track the frontier" idea, grown one notch.

Interactive Strategy Visualization

Goal Shifting

2
0
3
1
1
2
1
3
4
4
Let's see if index 0 can reach the end.
STRATEGY

Start from the end and work backwards. The last index is our initial goal.

REACHABILITY

If an earlier index can reach the current goal, that index becomes the new goal. If goal reaches index 0, we win.

Exponential Path Search
O(N²) Time Dynamic Programming
O(N) Time Greedy Frontier