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.
Constraints:
- $1 \leq$
nums.length$\leq 10^{4}$ - $0 \leq$
nums[i]$\leq 10^{5}$
Examples
| Input | Output | Explanation |
|---|---|---|
| [2, 3, 1, 1, 5] | True | Jump from index 0 to 1, then from index 1 to the last index. |
| [3, 2, 1, 0, 3] | False | You inevitably reach index 3, which has jump length 0, so you cannot progress to index 4. |
| [1, 2, 0, 1] | True | Jump from index 0 to 1, then from index 1 to index 3 (the last index). |
| [1, 1, 0, 1] | False | You 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:
- Initialize
farthest = 0andlast = len(nums)-1. - Iterate
ifrom0tolen(nums) - 1:- If
iis greater thanfarthest, returnFalse(this index is unreachable). - Update
farthest = max(farthest, i + nums[i]). - If
farthestis at least the last index (farthest >= last), returnTrue.
- If
- After processing all elements , return whether
farthestreaches the last index.
Take a look at the illustration below to understand the solution more clearly.
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, sofarthest >= lastis true immediately. - Early zero but still reachable past it
Input: [2,0,1]
Why the solution handles it: from index 0,farthestbecomes 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,farthestis still 1, so wheni = 2,i > farthesttriggersFalse. - Large jump from early index
Input: [10,0,0,0]
Why the solution handles it:farthestquickly covers the last index and returnsTrue.
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
farthestfor unreachable indices, you can incorrectly returnTrue. - Off-by-one errors with the last index: ensure you compare against
len(nums) - 1, notlen(nums). - Overcomplicating with DP: it’s correct, but often slower and more code than needed in interviews.