Level Up Your Coding Skills & Crack Interviews — Save up to 50% or more on Educative.io Today! Claim Discount

Arrow
Table of contents

55. Jump Game

Problem Statement

You’re given an array nums where nums[i] tells you the farthest you’re allowed to jump forward from index i. Starting at index $0$, determine whether there exists some sequence of jumps that lets you land on the final index.

The challenge is that early choices affect what becomes reachable later, and trying all jump options quickly repeats a lot of work. You need a way to reason about “how far can I get” without enumerating every possible jump path.

Constraints:

  • $1 \leq$ nums.length $\leq 10^{4}$
  • $0 \leq$ nums[i] $\leq 10^{5}$

Examples

InputOutputExplanation
[2, 3, 1, 1, 5]TrueJump from index 0 to 1, then from index 1 to the last index.
[3, 2, 1, 0, 3]FalseYou inevitably reach index 3, which has jump length 0, so you cannot progress to index 4.
[1, 2, 0, 1]TrueJump from index 0 to 1, then from index 1 to index 3 (the last index).
[1, 1, 0, 1]FalseYou can reach index 2, but its jump length is 0, so you get stuck before the last index.

Brute Force: Too Many Possibilities

A naive approach tries all possible jumps from each index (like exploring a decision tree). That quickly becomes expensive because from many indices you can branch to multiple next positions. Even with memoization, you may still scan many reachable edges repeatedly, and in the worst case it can degrade toward quadratic behavior for large arrays.

The overlapping work comes from re-evaluating reachability of the same suffixes: different jump sequences can land you on the same index, and brute force tends to “rediscover” those states.

Optimized Approach Using Greedy Algorithm

Instead of choosing specific jumps, track a single evolving fact: the farthest index you can reach so far. When you stand at index i, if i is already beyond your farthest reachable index, then you can’t even get to i, so the answer is immediately false. Otherwise, you can update your farthest reach using i + nums[i].

This makes the logic easy to follow: if at every reachable index you extend the boundary of what’s reachable, then reachability of the end is exactly the question “does this boundary ever cover the last index?”

Why this works even with zeros

Zeros are only a problem if they occur before your current farthest reachable boundary ends. The greedy invariant naturally handles this: a 0 contributes no extension, but you can still pass over it if your farthest reach was extended earlier. If a 0 causes the boundary to stop before the next index, you detect it as soon as you encounter an index you can’t reach.

Solution Steps

Below are the step-by-step instructions to implement the greedy solution:

  1. Initialize farthest = 0 and last = len(nums)-1.
  2. Iterate i from 0 to len(nums) - 1:
    1. If i is greater than farthest, return False (this index is unreachable).
    2. Update farthest = max(farthest, i + nums[i]).
    3. If farthest is at least the last index (farthest >= last), return True.
  3. After processing all elements , return whether farthest reaches the last index.

Take a look at the illustration below to understand the solution more clearly.

1 / 8

Python Implementation

Let’s look at the code for the solution we just discussed.

Time Complexity

The time complexity is $O(n)$ because you scan the array once and do constant work per index while maintaining the farthest reachable position.

Space Complexity

The space complexity is $O(1)$ because the algorithm only stores a few integers regardless of input size.

Jump Game: Edge Cases

Handle special inputs like single-element arrays, early zeros, and barriers that stop progress.

  • Single element array (already at the end)
    Input: [0]
    Why the solution handles it: last = 0, so farthest >= last is true immediately.
  • Early zero but still reachable past it
    Input: [2,0,1]
    Why the solution handles it: from index 0, farthest becomes 2, so index 1 being zero doesn’t block reaching index 2.
  • Zero creates a hard barrier
    Input: [1,0,2]
    Why the solution handles it: after index 1, farthest is still 1, so when i = 2, i > farthest triggers False.
  • Large jump from early index
    Input: [10,0,0,0]
    Why the solution handles it: farthest quickly covers the last index and returns True.

Common Pitfalls

Avoid mistakes like updating reachability from unreachable indices or relying on “always jump max” logic.

  • Trying to pick a “best next jump” explicitly: choosing locally largest jumps can miss cases where a smaller jump leads to a better launch point later.
  • Not checking reachability before updating: if you update farthest for unreachable indices, you can incorrectly return True.
  • Off-by-one errors with the last index: ensure you compare against len(nums) - 1, not len(nums).
  • Overcomplicating with DP: it’s correct, but often slower and more code than needed in interviews.

Frequently Asked Questions

Why doesn’t “always jump the maximum distance” work?

Because the best outcome depends on which index you land on, not just how far you go. A shorter jump can land you on an index with a larger future reach.

How do I recognize the Greedy (Farthest Reach Invariant) pattern?

When you only care whether the end is reachable (not the path), and each step can only move forward with a bounded range, tracking the farthest reachable boundary is a strong signal.

Is there a faster-than-O(n) solution?

No. You need to at least look at the array values up to the point where reachability is determined, which is linear in the worst case.

What happens if the array contains many zeros?

Zeros are fine as long as earlier positions extend farthest past them. The algorithm naturally detects when zeros cause the reachable boundary to stall.

How would the solution change if I needed the minimum number of jumps?

That becomes a different problem (often called “Jump Game II”) where you still use a greedy boundary idea, but you count boundary expansions rather than just checking reachability.

Share with others:

Leave a Reply

Your email address will not be published. Required fields are marked *