leetcode 算法之跳跃游戏

0 阅读3分钟

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。

 

示例 1:

输入: nums = [2,3,1,1,4]
输出: true
解释: 可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

示例 2:

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

 

提示:

  • 1 <= nums.length <= 104
  • 0 <= nums[i] <= 105

题目分析

  • 第一种办法

我们可以通过贪心算法找到我们的当前元素最远跳转的位置 然后不断的去更新 当我们的下标大于我们的最远位置 说明什么 就说明数组里面元素有 0 的值这个时候我们的需要返回false 然后判断我们最大跳转位置超越了 我们最后一个元素的下标就返回true

具体实现

public boolean canJump(int[] nums) {
    // 边界处理:空数组
    if (nums == null || nums.length == 0) {
        return false;
    }
    // 单元素数组,已经在终点
    if (nums.length == 1) {
        return true;
    }
    // 核心思路:维护当前能到达的最远位置
    int maxReach = nums[0];

    // 从位置1开始遍历(位置0已作为初始maxReach)
    for (int i = 1; i < nums.length; i++) {
        // 关键判断:当前位置是否可达
        if (i > maxReach) {
            return false;  // 当前位置超过了最远可达范围
        }

        // 更新最远可达位置(不用Math.max,用手动比较)
        int currentReach = i + nums[i];
        if (currentReach > maxReach) {
            maxReach = currentReach;
        }

        // 已经可以到达终点,提前返回
        if (maxReach >= nums.length - 1) {
            return true;
        }
    }

    return true;
}
  • 单元测试

public static void main(String[] args) {
    Leetcode4 solution = new Leetcode4();

    // 测试用例1: 可以到达终点 [2,3,1,1,4]
    int[] nums1 = {2, 3, 1, 1, 4};
    System.out.println("Test 1: " + solution.canJump(nums1)); // 期望输出: true

    // 测试用例2: 无法到达终点 [3,2,1,0,4]
    int[] nums2 = {3, 2, 1, 0, 4};
    System.out.println("Test 2: " + solution.canJump(nums2)); // 期望输出: false

    // 测试用例3: 单元素数组 [0]
    int[] nums3 = {0};
    System.out.println("Test 3: " + solution.canJump(nums3)); // 期望输出: true
}

测试结果

image.png

  • 第二种方法

从右到左来遍历 然后更新最远位置 如果最后跟我们的起点相等那么就返回true 否则就是返程false

public boolean canJump2(int[] nums) {
    // 记录需要覆盖的最远位置(从后往前看,就是需要被跳到的位置)
    int lastPos = nums.length - 1;

    // 从后往前遍历:检查每个位置能否跳到lastPos
    for (int i = nums.length - 2; i >= 0; i--) {
        if (i + nums[i] >= lastPos) {
            // 位置i可以到达lastPos,那么问题变成:能否到达位置i
            lastPos = i;
        }
    }

    // 最后看起点能否到达
    return lastPos == 0;
}
  • 测试用例

public static void main(String[] args) {
    Leetcode4 solution = new Leetcode4();

    // 测试用例1: 可以到达终点 [2,3,1,1,4]
    int[] nums1 = {2, 3, 1, 1, 4};
    System.out.println("Test 1: " + solution.canJump2(nums1)); // 期望输出: true

    // 测试用例2: 无法到达终点 [3,2,1,0,4]
    int[] nums2 = {3, 2, 1, 0, 4};
    System.out.println("Test 2: " + solution.canJump2(nums2)); // 期望输出: false

    // 测试用例3: 单元素数组 [0]
    int[] nums3 = {0};
    System.out.println("Test 3: " + solution.canJump2(nums3)); // 期望输出: true
}

测试结果

image.png