Skip to content
DSAPrep

    ↑↓ to move · Enter to open · Esc to close

    MediumGreedy

    Jump Game

    You are given an integer array nums. You are initially positioned at the array's first index, and each element in the array represents your maximum jump length at that position.

    Return true if you can reach the last index, or false otherwise.

    Example 1

    Input: nums = [2,3,1,1,4]

    Output: true

    Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.

    Example 2

    Input: nums = [3,2,1,0,4]

    Output: false

    Explanation: You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index.

    Constraints

    • 1 <= nums.length <= 10^4
    • 0 <= nums[i] <= 10^5
    View original on LeetCode ↗

    Dynamic Programming

    Time O(n²)Space O(n)

    Work backward: dp[i] is true if the last index is reachable starting from i. The last index is trivially reachable from itself. For every earlier index, check every index within jump range to see if any of them is already known to reach the end.

    class Solution:
    def canJump(self, nums: list[int]) -> bool:
    n = len(nums)
    dp = [False] * n
    dp[-1] = True
    for i in range(n - 2, -1, -1):
    furthest = min(i + nums[i], n - 1)
    for j in range(i, furthest + 1):
    if dp[j]:
    dp[i] = True
    break
    return dp[0]

    For each index we may scan up to nums[i] positions ahead, so the total work is O(n²) in the worst case, with O(n) space for the dp array.

    Greedy: Furthest Reachable Index

    OptimalTime O(n)Space O(1)

    Scan left to right and track the single number that matters: furthest, the farthest index reachable using jumps decided so far. At index i, if i is already beyond furthest, no earlier jump could have gotten here, so the last index is unreachable. Otherwise i is reachable, so update furthest = max(furthest, i + nums[i]).

    class Solution:
    def canJump(self, nums: list[int]) -> bool:
    furthest = 0
    for i, n in enumerate(nums):
    if i > furthest:
    return False
    furthest = max(furthest, i + n)
    return furthest >= len(nums) - 1

    Trace nums = [2,3,1,1,4]. Watch the reachable prefix grow: a cell is green because this jump extends furthest, gray because it was already covered, or dim beyond the frontier — and only a gap where i passes furthest could stop the scan.

    Reachable prefix

    02
    13
    21
    31
    44
    i0
    jump i + nums[i]2
    furthest0
    start
    1 / 7
    currentseenresult

    Start with furthest 0, so only index 0 is already reachable. It sits on the frontier, so the scan begins: its jump 0 + 2 tries to extend it.

    Why it’s correct: furthest only ever needs to record the single best jump destination seen so far — the specific index that produced it never matters, because from any reachable index we could have re-derived the same or a smaller reach. Discarding “which index gave us this reach” loses no information relevant to future decisions, which is exactly what makes the greedy choice safe. Complexity: one pass, one running variable → O(n) time, O(1) space.

    More Greedy practice