一、题目
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
https://leetcode-cn.com/problems/jump-game/
二、解题思路
整体思路
1、能否到达最后一个位置
--> 最多能跳多远,如果能跳过最后一个,则为true
2、最值问题
--> 动态规划/贪心
关键问题:最多能跳多远?
贪心
不是顺着值计算去跳跃。
思路1:每一步都计算一下从当前位置最远能够跳到哪里,如果能跳到最后一个位置处就为true。实现见题解1
问题2:会出现badcase1 eg [0,2,3]的情况,即有0处被跳过了,应该为false,最后错误输出了true
思路2: 再加上对0的处理,如果不能往后面跳(max==i),则输出false。实现见题解2
问题2: eg [3,0,8,2,0,0,1] 在0处跳出了,其实可以不走0处,跳到后面然后可以有解,所以应该输出为true,错误输出了true
eg [0]也需要注意
正确思路:
设置一个全局最优的最远位置 farthest 做对比,通过每一步的最优解,更新全局最优解,这就是贪心。
1、如果某一个作为 起跳点 的格子可以跳跃的距离是 3,那么表示后面 3 个格子都可以作为 起跳点。
2、可以对每一个能作为 起跳点 的格子都尝试跳一次,把 能跳到最远的距离 不断更新。
3、如果可以一直跳到最后,就成功了。
(很难想到啊emmmmmm)
三、题解
暴力解法
题解1:
Java题解
class Solution {
public boolean canJump(int[] nums) {
if (nums.length == 0 || nums.length == 1) {
return true;
}
int max_step = 0, len = nums.length;
for (int i = 0; i < len - 1; i++) {
max_step = i + nums[i];
if (max_step >= (len - 1)) {
return true;
}
}
return false;
}
}
badcase1
[0,2,3]
题解2
Java题解
// badcase
// [0]
// [3,0,8,2,0,0,1]
class Solution {
public boolean canJump(int[] nums) {
if (nums.length == 0 || nums.length == 1) {
return true;
}
int max_step = 0, len = nums.length;
for (int i = 0; i < len - 1; i++) {
max_step = i + nums[i];
if (max_step >= (len - 1)) {
return true;
}
if (max_step == i) {
return false;
}
}
return false;
}
}
badcase2
题解3
Java题解
错误解答
class Solution {
public boolean canJump(int[] nums) {
if (nums.length == 0 || nums.length == 1) {
return true;
}
int max_step = 0, len = nums.length;
for (int i = 0; i < len; i++) {
max_step = Math.max(i + nums[i], max_step); //
if (max_step >= (len - 1)) {
return true;
}
if (max_step == i) {
return false;
}
}
return false;
}
}
错误案例
输入:[2,5,0,0]
输出:false
预期结果:true
正确题解
注意for循环的n-1,遍历的是起跳点
class Solution {
public boolean canJump(int[] nums) {
if (nums.length == 0 || nums.length == 1) {
return true;
}
int max_step = 0, len = nums.length;
for (int i = 0; i < len - 1; i++) {
max_step = Math.max(i + nums[i], max_step); //
if (max_step >= (len - 1)) {
return true;
}
if (max_step == i) {
return false;
}
}
return false;
}
}
结果
执行用时:2 ms, 在所有 Java 提交中击败了79.34%的用户
内存消耗:42.1 MB, 在所有 Java 提交中击败了9.80%的用户
复杂度分析
时间复杂度:O(n),遍历一遍数组
空间复杂度:O(1)
四、测试数据
1、[2,5,0,0] true
2、[0] true
n==1
3、[2, 0, 0] true
--> n-1
参考
1、题解参考
2、优秀题解
https://leetcode-cn.com/problems/jump-game/solution/55-by-ikaruga/