Jump Game
Each entry says the furthest you may jump forward from that position. Starting at the first, decide whether the last is reachable.
- reach
- 0
Carry one number: the furthest index anything can reach so far.
1def can_jump(nums):2 reach = 03 for i, n in enumerate(nums):4 if i > reach:5 return False6 reach = max(reach, i + n)7 return TrueRead the 16 steps as text
- 1Carry one number: the furthest index anything can reach so far.
- 2At index 0, which allows a jump of 3.
- 3From here you can get to index 3. Reach extends to 3.
- 4At index 1, which allows a jump of 1.
- 52 is no further than 3. Reach is unchanged.
- 6At index 2, which allows a jump of 0.
- 72 is no further than 3. Reach is unchanged.
- 8At index 3, which allows a jump of 4.
- 9From here you can get to index 7. Reach extends to 7.
- 10At index 4, which allows a jump of 1.
- 115 is no further than 7. Reach is unchanged.
- 12At index 5, which allows a jump of 1.
- 136 is no further than 7. Reach is unchanged.
- 14At index 6, which allows a jump of 2.
- 15From here you can get to index 8. Reach extends to 8.
- 16Reach never fell behind, so the last index is reachable.
The idea
The instinct is to search โ try every jump length from every position and see if any route arrives. That's exponential, and memoizing it is still O(nยฒ).
But you never actually need to know *which* route works. You only need to know how far it is possible to get, and that is a single number.
Sweep left to right carrying the furthest index reached so far. At position i you can extend that to i + nums[i]. If the sweep ever arrives at a position further than anything could reach, there's a gap nothing crosses and the answer is no.
The reason greedy is safe here โ and it's the question an interviewer will ask โ is that reachability is downward closed: if you can reach index k, you can reach every index before it, because the jumps allow any distance up to the maximum. So one running maximum captures everything a full search would find.
The approach
- 1Keep `reach`, the furthest index known to be reachable, starting at 0.
- 2Walk forward. If the current index is beyond `reach`, no route got here โ return false.
- 3Otherwise extend `reach` to the larger of itself and i + nums[i].
- 4Surviving the whole sweep means the last index was reachable.
Complexity
One pass and one integer. No route is ever reconstructed because none is asked for.
Code
def can_jump(nums):
reach = 0
for i, n in enumerate(nums):
if i > reach:
return False
reach = max(reach, i + n)
return TrueWhat goes wrong
- โขChecking `reach >= last` only at the end. It's correct but does needless work; bailing the moment i passes reach is what makes early exit possible.
- โขTreating a zero as fatal. A zero is only fatal if nothing behind it jumps over it โ plenty of arrays contain zeros and still succeed.
- โขConfusing this with Jump Game II, which asks for the minimum number of jumps. Same array, different algorithm โ that one needs the current jump's boundary tracked as well.