题目描述

给定一个非负整数数组,你最初位于数组的第一个位置。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个位置。

示例 1:

输入: [2,3,1,1,4]
输出: true
解释: 从位置 0 到 1 跳 1 步, 然后跳 3 步到达最后一个位置。

示例 2:

输入: [3,2,1,0,4] 输出: false 解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。

https://leetcode-cn.com/problems/jump-game/

解法1

解法1的方法是一种暴力搜索的方法,既然给出了每个位置能跳跃的最大距离,那我们就挨个尝试能落下的位置,然后以该位置为起点继续重复此过程看看能不能到达末尾。这是一种DFS方法,时间复杂度为O(n^2)。这种做法属于“人思考的少,机器思考的多”,另外代码量也很大,所以不推荐这种做法。

class Solution {
    public boolean canJump(int[] nums) {
        if (nums.length == 0)
            return false;

        int[] cache = new int[nums.length];
        for (int i = 0; i < cache.length; i++)
            cache[i] = -1;

        return canJump(nums, 0, cache);
    }

    public boolean canJump(int[] nums, int start, int[] cache) {
        if (cache[start] != -1)
            return cache[start] == 1;

        if (start == nums.length - 1)
            return true;
        int steps = nums[start];
        boolean can = false;

        for (int i = 1; i <= steps; i++)
            if (start + i < nums.length) {
                can |= canJump(nums, start + i, cache);
            }

        if (can)
            cache[start] = 1;
        else
            cache[start] = 0;

        return can;
    }
}

解法2

解法2采用贪心的做法,设置一个变量currMax,表示从当前位置之前的任意一点出发能走到的最远的位置。我们遍历每一个位置,判断i是否大于currMax。如果i>currMax,物理意义表示从i之前的任意位置出发,都到达不了i,则肯定到达不了i之后的任何位置,返回false即可。否则,我们更新currMax = max(currMax, i + nums[i])。

class Solution {
    public boolean canJump(int[] nums) {
        int currMax = 0; // 表示从i之前的任意一点出发能走到的最远位置
        
        for(int i=0;i<nums.length;i++){
            if(i > currMax) return false;
            currMax = Math.max(currMax, i + nums[i]);
        }
        
        return true;
    }
}

解法3

解法3采用回溯的方法,我们从终点向前回溯,看看终点之前有没有一个点i至少能够到达终点的,如果存在则回溯到点i;我们再看看i之前有没有一个点至少能够到达点i,如果存在我们继续回溯……直到看看能不能回溯到起点。如果能够回溯到起点,那我们从起点正向出发也一定能够到达终点;反之如果不能回溯到起点,那我们就没办法到达终点。

class Solution {
    public boolean canJump(int[] nums) {
        int lastStart = nums.length - 1;
        
        for(int start = nums.length-2;start>=0;start--){
            if(nums[start] >= lastStart - start){
                lastStart = start;
            }
        }
        
        return lastStart == 0;
    }
}
pwrliang Algorithms, Array, Greedy , ,

Leave a Reply

Your email address will not be published. Required fields are marked *