Leetcode 55. Jump Game [medium][java]

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Determine if you are able to reach the last index.

Example
在这里插入图片描述

Ignored Case: time limitation
在这里插入图片描述

Solution 1: Backtracking
Cannot solve time limitation case
Consideration

  1. We start from the first index, and jump to every index it can jump to. If the index reaches the end index, return true.

==Time complexity: O(2^n), where n is the length of the array. Space complexity: O(n). Recursion requires additional memory for the stack frames. ==

class Solution {
    public boolean canJump(int[] nums) {
        return canJumpFromPosition(0, nums);
        
    }
    
    public boolean canJumpFromPosition(int position, int[] nums) {
        if (position == nums.length - 1) {
            return true;
        }

        int furthestJump = Math.min(position + nums[position], nums.length - 1);
        for (int nextPosition = furthestJump; nextPosition > position; nextPosition--) {
            if (canJumpFromPosition(nextPosition, nums)) {
                return true;
            }
        }

        return false;
    }
}

Solution 2: dynamic programming top-down
Consideration

  1. We use an array to store the result of each index. If the index can jump to the end, the result is GOOD. If cannot, the result if BAD. If haven’t been visited, the result is UNKOWN.

Time complexity: O(n^2). For every element in the array, say i, we are looking at the next nums[i] elements to its right aiming to find a GOOD index. nums[i] can be at most n, where n is the length of array nums.
==Space complexity : O(2n) = O(n). First n originates from recursion. Second n comes from the usage of the memo table. ==

enum Index {
    GOOD, BAD, UNKOWN
}

class Solution {
    Index[] memo;
    public boolean canJump(int[] nums) {
        memo = new Index[nums.length];
        for(int i = 0; i < nums.length; i++)
            memo[i] = Index.UNKOWN;
        memo[nums.length-1] = Index.GOOD;
        return canJumpFromPosition(0, nums);
    }
    
    public boolean canJumpFromPosition(int position, int[] nums) {
        if(memo[position] != Index.UNKOWN)
            return memo[position]==Index.GOOD?true:false;
        int furthestJump = Math.min(position+nums[position], nums.length-1);
        //If we start from position, the last testing case will be time limited.
        for(int nextPosition = furthestJump; nextPosition >= position+1; nextPosition--) {
            if(canJumpFromPosition(nextPosition, nums)) {
                memo[position] = Index.GOOD;
                return true;
            }
        }
        
        memo[position] = Index.BAD;
        return false;
    }
}

Solution 3: dynamic programming bottom-up
Consideration

  1. Top-down to bottom-up conversion is done by eliminating recursion.
  2. We start from the right end of the array. When we query to the right of this position, the memo already stored a result. We can hit the memo array.

Time complexity : O(n^2). For every element in the array, say i, we are looking at the next nums[i] elements to its right aiming to find a GOOD index. nums[i] can be at most nn, where nn is the length of array nums.
Space complexity: O(n). We use memo array to store the result.

enum Index {
    GOOD, BAD, UNKOWN
}

class Solution {
    Index[] memo;
    public boolean canJump(int[] nums) {
        memo = new Index[nums.length];
        for(int i = 0; i < nums.length; i++)
            memo[i] = Index.UNKOWN;
        memo[nums.length-1] = Index.GOOD;
        
        //iterate from the right end of the array
        for(int i = nums.length-2; i >= 0; i--) {
            int furthestJump = Math.min(i+nums[i], nums.length-1);
            for (int j = i + 1; j <= furthestJump; j++) {
                if(memo[j] == Index.GOOD) {
                    memo[i] = Index.GOOD;
                    break;
                }
            }
        }
        
        return memo[0] == Index.GOOD;
    }
    
}

Solution 4: greedy (very clever one)
Consideration

  1. We start from the right end of the array. If the current index i of the considering number plus nums[i] is not less than the last index of the array, then the current index can reach to the end. We store the current index as the lastPos to be considered.
  2. Next time, we only need to consider if the current index can reach to the lastPos. If yes, then this index can finally reach to the end.
  3. At last, we only need to see if the lastPos is equal to 0.

Time complexity: O(n), space complexity: O(1), We are not using any extra memory.

class Solution {
    public boolean canJump(int[] nums) {
        int lastPosition = nums.length-1;
        //iterate from the right end of the array
        for(int i = nums.length - 2; i >= 0; i--) {
             if(i+nums[i] >= lastPosition) 
                 lastPosition = i;
        }
        
        return lastPosition == 0;
    }
    
}

References

  1. https://leetcode.com/problems/jump-game/solution/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值