You are given an integer array nums where each element nums[i] indicates your maximum jump length at that position.
Return true if you can reach the last index starting from index 0, or false otherwise.
Example 1:
Input: nums = [1,2,0,1,0]
Output: trueExplanation: First jump from index 0 to 1, then from index 1 to 3, and lastly from index 3 to 4.
Example 2:
Input: nums = [1,2,1,0,1]
Output: falseConstraints:
1 <= nums.length <= 10000 <= nums[i] <= 1000
You should aim for a solution with O(n) time and O(1) space, where n is the size of input array.
A brute force approach would be to recursively explore all paths from index 0 to its reachable indices, then process those indices similarly, returning true if we reach the last index. This would be an exponential approach. Can you think of a better way? Maybe a greedy approach works.
Instead of processing the array from index 0, start from the last index. Let the target index be goal = n - 1. Iterate in reverse from index n - 2.
At each iteration, we check whether the current index can reach goal. If it can, we update goal to the current index, as reaching the current index means we can also reach the goal.
To determine if we can reach the last index, the goal should be 0 after the iteration. Otherwise, reaching the last index is not possible.
Before attempting this problem, you should be comfortable with:
This problem asks whether we can reach the last index of the array starting from the first index.
At every position i, the value nums[i] tells us the maximum jump length from that index.
So from index i, we can jump to any index between i + 1 and i + nums[i].
Using recursion, we try all possible jumps from the current index and see if any path eventually reaches the last index.
The recursive function represents:
"Is it possible to reach the last index starting from index i?"
If we ever reach the last index, we know the answer is true.
dfs(i):i is the current indexi is already at the last index:truei:end = min(last_index, i + nums[i])i + 1 to end:dfs(j)true, return truefalse0This problem asks whether we can reach the last index of the array starting from index 0.
At each index i, the value nums[i] tells us how far we can jump. From there, we can choose any next index within that jump range.
The plain recursive approach explores all possible jumps, but it repeats the same work many times.
To avoid this, we use top-down dynamic programming (memoization).
The recursive function represents:
"Can we reach the last index starting from index i?"
Once we know the answer for an index, we store it so we never recompute it.
memo:memo[i] stores whether the last index is reachable from index idfs(i):i is the current indexi is already in memo:i is the last index:truenums[i] == 0:falseitrue, store true in memo[i] and return itfalse in memo[i] and return it0class Solution:
def canJump(self, nums: List[int]) -> bool:
memo = {}
def dfs(i):
if i in memo:
return memo[i]
if i == len(nums) - 1:
return True
if nums[i] == 0:
return False
end = min(len(nums), i + nums[i] + 1)
for j in range(i + 1, end):
if dfs(j):
memo[i] = True
return True
memo[i] = False
return False
return dfs(0)We want to know if we can reach the last index starting from index 0.
Instead of using recursion, we can solve this using bottom-up dynamic programming by working backwards from the end of the array.
The idea is simple:
If index i can jump to any index j that is already reachable, then i is also reachable.
n be the length of the array.dp of size n:dp[i] = true means the last index is reachable from index idp[n - 1] = true since the last index can trivially reach itselfi from n - 2 down to 0:i:end = min(n, i + nums[i] + 1)i:dp[j] is true, then set dp[i] = truedp[0]We want to check if we can reach the last index starting from index 0.
Instead of trying all possible jumps, we can think about the problem in reverse:
We keep a variable called goal:
As we move backward through the array:
i we can jump to the current goal (or beyond), then index i becomes the new goalAt the end, if index 0 becomes the goal, it means we can reach the last index.
goal as the last index of the array.0.i:i + nums[i] >= goalgoal = i because index i can reach the previous goalgoal == 0, return truefalseThe value nums[i] represents the maximum jump length, not the destination index. From position i, you can reach any index in [i + 1, i + nums[i]], not just i + nums[i]. Treating the jump value as a fixed destination misses valid shorter jumps.
A zero at position i means you cannot move forward from that position. If all paths lead to a position with nums[i] == 0 before reaching the end, the answer is false. Ensure your algorithm properly detects when you are stuck.
The greedy approach works backward, updating the goal position. A common mistake is iterating forward and incorrectly maintaining state. When going backward, the condition i + nums[i] >= goal correctly checks reachability.