方法一:使用一个布尔数组记住结果

这里有很多重复计算。

public class Solution11 {

    public boolean canJump(int[] nums) {
        int len = nums.length;

        if (len < 2) {
            return true;
        }


        boolean[] reached = new boolean[len];
        reached[0] = true;

        for (int i = 0; i < len; i++) {

            if (reached[i]) {
                for (int j = i; j < len && j <= i + nums[i]; j++) {
                    reached[j] = true;
                }
            } else {
                return false;
            }

        }
        return reached[len - 1];
    }
}

「力扣」第 55 题:跳跃游戏(贪心算法)_贪心算法

方法二:贪心算法

public class Solution {

    public boolean canJump(int[] nums) {
        int len = nums.length;

        if (len < 2) {
            return true;
        }


        // 贪心算法:贪最远的下标
        int maxReached = 0;

        for (int i = 0; i < len; i++) {
            if (maxReached >= len - 1) {
                return true;
            }

            if (i <= maxReached) {
                maxReached = Math.max(maxReached, i + nums[i]);
            } else {
                return false;
            }

        }
        return true;
    }
}

方法一:模拟(暴力解法)

Java 代码:

class Solution {
    public boolean canJump(int[] nums) {
        int len = nums.length;
        if (len < 1) {
            return false;
        }
        
        // 按照题意模拟
        
        boolean[] reached = new boolean[len];
        reached[0] = true;
        
        for (int i = 0; i < len; i++) {
            // 如果当前这个位置不能到达,就返回 false
            if (!reached[i]) {
                return false;
            }

            // 在 i + nums[i] 和 len - 1 里选最远的,把它们都赋值成为 True
            int maxReach = Math.min(len - 1, i + nums[i]);
            for (int j = i + 1; j <= maxReach; j++) {
                reached[j] = true;
            }
        }
        
        // 看最后一个位置是否可以到达
        return reached[len - 1];
    }
}

方法二:递归

Java 代码:(大数据的时候超时,应该加上记忆化)

class Solution {
    
    // 递归(有很多重复子问题)

    public boolean canJump(int[] nums) {
        return canJumpFromPosition(nums, 0);
    }

    public boolean canJumpFromPosition(int[] nums, int curIndex) {
        int len = nums.length;
        if (curIndex == len - 1) {
            return true;
        }

        int maxReach = Math.min(curIndex + nums[curIndex], len - 1);

        for (int i = curIndex + 1; i <= maxReach; i++) {
            if (canJumpFromPosition(nums, i)) {
                return true;
            }
        }

        return false;
    }
}

Java 代码:

方法三:贪心算法

Java 代码:

public class Solution10 {

    public boolean canJump(int[] nums) {
        int len = nums.length;
        if (len == 0) {
            return true;
        }

        // 时间复杂度:O(N)

        // 从后往前写
        boolean[] can = new boolean[len];
        can[len - 1] = true;

        // 最左边可以到达的数组下标
        int left = len - 1;

        for (int i = len - 2; i >= 0; i--) {

            // 贪心算法核心步骤
            can[i] = (i + nums[i] >= left);
            if (can[i]) {
                left = i;
            }

        }
        // 第 1 个位置能够得到即可
        return can[0];
    }
}