题目介绍
力扣55题:https://leetcode-cn.com/problems/jump-game/
给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。
数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标。
分析
这道题规定数组每个元素,就代表了可以跳跃的最大长度。我们发现,其实只要判断出当前最远可以到达的位置,那么在这之前的元素,其实统统可以跳过。所以我们采用的,就是一个贪心策略:每次都判断一下当前能到达的最远位置,然后再看接下来最远可以到哪里。
解决方法
我们可以遍历数组中的每一个位置,并实时更新当前最远可以到达的位置,记为farthest。对于当前遍历到的位置i,如果它小于等于当前farthest,说明可以从起点通过若干次跳跃到达i;接下来基于i最远又可以跳到i+nums[i],所以我们取farthest和i+nums[i]的最大值,就是新的farthest。
在遍历的过程中,如果 最远可以到达的位置 大于等于数组中的最后一个位置,那就说明最后一个位置可达,我们就可以直接返回 True 作为答案。反之,如果在遍历结束后,最后一个位置仍然不可达,我们就返回 False 作为答案。
代码演示如下:
public class JumpGame {
// 贪心实现
public boolean canJump(int[] nums){
// 定义一个变量,保存当前最远能跳到的位置
int farthest = 0;
// 遍历数组,更新farthest
for (int i = 0; i < nums.length; i++){
// 判断当前i在可以到达的范围内,更新farthest
if (i <= farthest){
farthest = Math.max(farthest, i + nums[i]);
// 如果farthest已经达到了末尾,直接返回true
if (farthest >= nums.length - 1)
return true;
} else {
// 如果i已经到不了了
return false;
}
}
return false;
}
public static void main(String[] args) {
JumpGame jumpGame = new JumpGame();
int[] nums1 = {2,3,1,1,4};
int[] nums2 = {3,2,1,0,4};
System.out.println(jumpGame.canJump(nums1));
System.out.println(jumpGame.canJump(nums2));
}
}
复杂度分析
- 时间复杂度:O(n),其中 n 为数组的大小。只需要访问 nums 数组一遍,共 n 个位置。
- 空间复杂度:O(1),不需要额外的空间开销。