题目的核心就是判断最终是否能够到达最后一个下标,这里提供两种思路:

第一种思路是动态规划,我们可以设置一个boolean类型的数组用来记录每走一步哪些地方可以被访问到,最后输出这个boolean类型数组的最后一个值,代码如下:

class Solution {
    public boolean canJump(int[] nums) {
        int n = nums.length;
        if (n == 1) {
            return true; // 只有一个元素时,本身就在终点
        }
        boolean[] isReachable = new boolean[n];
        isReachable[0] = true; // 起点可达

        for (int i = 0; i < n; i++) {
            if (isReachable[i]) { // 仅处理可达的位置
                int maxJump = i + nums[i]; // 从i能跳到的最远位置
                // 标记从i+1到maxJump之间的所有位置为可达(不超过数组边界)
                for (int j = i + 1; j <= Math.min(maxJump, n - 1); j++) {
                    isReachable[j] = true;
                    // 提前判断:如果已经到达最后一个位置,直接返回true
                    if (j == n - 1) {
                        return true;
                    }
                }
            }
        }
        // 循环结束后检查最后一个位置是否可达
        return isReachable[n - 1];
    }
}

根据上面的代码我们不难发现每当我们访问一个>=2的数组时后面的boolean类型数组很容易赋值两次,而且动态规划思路必须标记所有可达位置,因为中间某个位置可能是到达终点的必经之路。

如果想优化效率,建议用贪心算法,只跟踪 “当前最远可达位置”,如果最远位置把最后一个下标包含进去了就说明可以到达,反之不能,代码如下:

class Solution {
    public boolean canJump(int[] nums) {
        //设置一个最远能达到的距离,如果最远能达到的地方覆盖了终点就说明可以,反之不能
        int n = nums.length;
        int maxReach = 0;
        for(int i=0;i<n;i++){
            //如果最远的地方到不了了,就返回false
           if(maxReach < i){
              return false;
           }
           maxReach = Math.max(maxReach,i + nums[i]);//更新max
           //如果超过了数组,就返回true
           if(maxReach >= n-1){
              return true;
           }
        }
        //循环结束后仍然没有到达
        return false;
    }
}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐