题目描述:
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
解法:
回溯算法:
思想:
本题较容易想到的就是回溯算法,我们模拟元素能够跳转的所有位置,直到可以跳转到最后一个元素时,返回true;但这个算法时间复杂度较高为O(2^n)
详细代码:
public static boolean canJump(int[] nums) {
return j(0,nums);
}
public static boolean j(int position,int[] nums) {
if(position == nums.length-1) {
return true;
}
int jumpLength = Math.min(nums[position]+position, nums.length-1);
for(int nextPosition = position+1;nextPosition<=jumpLength;nextPosition++) {
if(j(nextPosition, nums)) {
return true;
}
}
return false;
}
动态规划算法:
思想:
题目要求:第一个元素能否跳到最后一个元素,那么我们可以将问题转换为能否由倒数第二人个元素跳转到最后一个元素,然后以此类推,就是判断元素能否从第一个元素跳转到第二个元素。时间复杂度是O(n^2)
详细代码:
class Solution {
public boolean canJump(int[] nums) {
if(nums==null) return false;
boolean[] db = new boolean[nums.length];
db[0] = true;
for(int i =1;i<nums.length;i++){
for(int j = 0;j<i;j++){
//判断在j的位置能否由前面的其他元素跳转到,并且要使在j上的元素能够跳转到指定i位置上,满足条件才能将i置为true,代表可以由第一个元素跳转到第i个位置
if(db[j]&&nums[j]+j>=i){
db[i] =true;
break;
}
}
}
return db[nums.length-1];
}
}
贪心算法:
思想:
贪心算法可以看成时上面动态规划算法的改进,从后往前判断i是否可以跳转到lastPosition,如果可以,就将lastPosition置为i;然后再开始循环,最后如果lastPosition==0,代表可以从初始位置跳转到最后位置。时间复杂度为:O(n)
详细代码:
class Solution {
public boolean canJump(int[] nums) {
if(nums==null) return false;
int lastPosition = nums.length-1;
for(int i = lastPosition;i>=0;i--){
if(nums[i]+i>=lastPosition){
lastPosition = i;
}
}
return lastPosition==0;
}
}