给你一个非负整数数组 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 <= 1040 <= 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
}
测试结果
-
第二种方法
从右到左来遍历 然后更新最远位置 如果最后跟我们的起点相等那么就返回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
}