跳跃游戏
给定一个非负数数组,每个元素代表该位置的最大跳跃长度,判断能否到达最后一个下标。
第一个想法,用递归暴力求解,但是马上否定了,这样过于浪费时间,而且代码也不好写。
想着探索每一条线路的话会造成重复的情况,于是设想出一个目前可达区域的概念,因为每个元素代表的是该位置的最大跳跃长度,也就是说这个长度是可调的,目前可以到达的最远地方以内的区域我们都是可以到的,而我们对于下一步可达区域就不以具体的路径来看,而是以目前可达区域来进一步扩展,如果区域没有到达终点而且无法进一步扩展的话,那么就无法到达。
class Solution {
public boolean canJump(int[] nums) {
if(nums.length <= 1) return true;
int reach = nums[0];
int pre = 0;
while(!(reach == pre)) {
pre = reach;
for (int i = 0; i <= reach; i++) {
if(reach >= nums.length - 1) return true;
if(i + nums[i] > reach) reach = i + nums[i];
}
}
return false;
}
}
稍加优化,每次探索下一步的时候不需要再次探索上次的区域,因为上次区域的极限就是当前区域了,遍历一遍上次区域和当前区域之间的新增加的区域就好。
class Solution {
public boolean canJump(int[] nums) {
if(nums.length <= 1) return true;
int reach = nums[0];
int pre = 0;
while(!(reach == pre)) {
int temp = pre + 1;
pre = reach;
for (int i = temp; i <= reach; i++) {
if(reach >= nums.length - 1) return true;
if(i + nums[i] > reach) reach = i + nums[i];
}
}
return false;
}
}