Maximum Number of Jumps to Reach the Last Index

Medium
Watch on YouTube ↗

Solution

/**
 * LeetCode 2770 - Maximum Number of Jumps to Reach the Last Index
 *
 * From index i, you can jump to j if |nums[j] - nums[i]| <= target.
 * Return the maximum number of jumps to reach the last index, or -1 if unreachable.
 *
 * Time:  O(n^2)  |  Space: O(n)
 */
class MaximumJumps {

    // -------------------------------------------------------------------------
    // Approach 1: Top-down DP (Memoized Recursion)
    // -------------------------------------------------------------------------

    Integer[] dp;

    public int maximumJumpsTopDown(int[] nums, int target) {
        dp = new Integer[nums.length];
        return helper(0, nums, target);
    }

    private int helper(int ind, int[] nums, int target) {
        if (ind == nums.length - 1) return 0;
        if (dp[ind] != null) return dp[ind];

        int jumps = -1;
        for (int i = ind + 1; i < nums.length; i++) {
            if (Math.abs(nums[i] - nums[ind]) <= target) {
                int next = helper(i, nums, target);
                if (next != -1)
                    jumps = Math.max(jumps, next + 1);
            }
        }

        return dp[ind] = jumps;
    }

    // -------------------------------------------------------------------------
    // Approach 2: Bottom-up DP (Iterative)
    // Iterate right to left; dp[i] = max jumps from i to last index (-1 if unreachable)
    // -------------------------------------------------------------------------

    public int maximumJumpsBottomUp(int[] nums, int target) {
        int n = nums.length;
        int[] dp = new int[n];
        Arrays.fill(dp, -1);
        dp[n - 1] = 0;

        for (int ind = n - 2; ind >= 0; ind--) {
            for (int i = ind + 1; i < n; i++) {
                if (Math.abs(nums[i] - nums[ind]) <= target && dp[i] != -1)
                    dp[ind] = Math.max(dp[ind], 1 + dp[i]);
            }
        }

        return dp[0];
    }
}