Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.
For example:
A = [2,3,1,1,4]
, return true
.
A = [3,2,1,0,4]
, return false
.
题意:给定一个非负数组,从数组首位开始跳,每次跳的距离最大为你所处位置元素的值,请问是否可以跳到数组的末尾位置。
首先,我们注意到,如果数组元素值都为正数,那么肯定可以跳到末尾,所以我们需要考虑的是数组元素为0的情况。
假设数组的第i位元素为0,那么什么情况下会出现不能继续往后跳呢?显然,当第i-1位元素小于等于1,第i-2位元素小于等于2,……第i-n位元素小于等于n时,我们始终无法跳过0这个元素,也就不可能再继续往后跳了。这是判断此题的关键点。
下面是代码:
public class Solution {
public boolean canJump(int[] nums) {
if(nums.length == 1)
return true;
if(nums[0] == 0)
return false;
for(int i=nums.length-2;i>0;i--){ //找到0所在的位置
if(nums[i] == 0){
boolean b = false;
for(int j=i-1;j>=0;j--){ //判断该位置是否可以跳过去
if(nums[j] > i-j){
b = true;
break;
}
}
if(b == false)
return b;
}
}
return true; //所有的0都可以跳过去或者数组中没有0
}
}
上面的我自己想到的第一种解法,在LeetCode上超越了38%左右的方法,这不是一种比较优的方法;
点开题目的提示信息,它告诉我们使用Greedy,也就是贪心的思想。这让我豁然开朗。
下面这种解法的思路是:假设我们从数组的i下标开始跳,如果nums[i]==0,那么此时就无法往后跳了,直接返回false;
如果nums[i]>0,那么我们可以选择跳1步,跳2步……跳nums[i]步,利用贪心算法,我们需要跳的最远,所以我们计算1+nums[i+1]、2+nums[i+2]……nums[i]+nums[i+nums[i]]这些值中的最大值,来决定跳的步数,直到可以跳到末尾。
下面是代码:
public class Solution {
public boolean canJump(int[] nums) {
if(nums.length == 1)
return true;
if(nums[0] == 0)
return false;
return canJump(nums,0);
}
public boolean canJump(int[] nums, int index){
while(index < nums.length-1 && nums[index] == 1){
index++;
}
if(index == nums.length-1)
return true;
if(nums[index] == 0)
return false;
if(index+nums[index] >= nums.length-1)
return true;
int maxdex = 0;
int maxval = 0;
for(int i=1;i<=nums[index];i++){
if(i+nums[index+i] > maxval){
maxval = i+nums[index+i];
maxdex = i;
}
}
return canJump(nums,maxdex+index);
}
}