给出一个非负整数数组,你最初定位在数组的第一个位置。
数组中的每个元素代表你在那个位置可以跳跃的最大长度。
判断你是否能到达数组的最后一个位置。
注意事项
这个问题有两个方法,一个是贪心和 动态规划。
贪心方法时间复杂度为O(N)。
动态规划方法的时间复杂度为为O(n^2)。
我们手动设置小型数据集,使大家可以通过测试的两种方式。这仅仅是为了让大家学会如何使用动态规划的方式解决此问题。如果您用动态规划的方式完成它,你可以尝试贪心法,以使其再次通过一次。
样例
A = [2,3,1,1,4],返回 true.
A = [3,2,1,0,4],返回 false.
标签
贪心 数组 动态规划
相关题目
中等 流浪剑客斯温 32 %
中等 跳跃游戏 II 35 %
(1)Java
package Greedy;
// version 2: Greedy
public class JumpGame {
public boolean canJump(int[] A) {
// think it as merging n intervals
if (A == null || A.length == 0) {
return false;
}
int farthest = A[0];
for (int i = 1; i < A.length; i++) {
if (i <= farthest && A[i] + i >= farthest) {
farthest = A[i] + i;
}
}
return farthest >= A.length - 1;
}
}
// version 1: Dynamic Programming
// 这个方法,复杂度是 O(n^2) 可能会超时,但是依然需要掌握。
class JumpGame1 {
public boolean canJump(int[] A) {
boolean[] can = new boolean[A.length];
can[0] = true;
for (int i = 1; i < A.length; i++) {
for (int j = 0; j < i; j++) {
if (can[j] && j + A[j] >= i) {
can[i] = true;
break;
}
}
}
return can[A.length - 1];
}
}
③维护一个right (表示右边能跳到的最远的点),从左往右扫描,根据当前可跳的步骤不断更新right ,当right到达终点,即可返回true. 若更新完right后,right未动,并且index = right,而且这时没到达终点,代表我们不可能到达终点了。(当前index的可跳值应该是0)。
class JumpGame2 {
// solution 3: one pass.
public boolean canJump(int[] A) {
// 4:42
if (A == null) {
return false;
}
int len = A.length;
int right = 0;
for (int i = 0; i < A.length; i++) {
right = Math.max(right, i + A[i]);
if (right == len - 1) {
return true;
}
if (i == right) {
return false;
}
}
return true;
}
}
其他方法:www.cnblogs.com/yuzhangcmu/p/4039840.html
(2)C++
class JumpGame{
public:
bool canJump(vector<int>& nums){
vector<int> index;// 每个位置i处所能 最远跳至的index下标
for(int i = 0; i < nums.size(); i++){
index.push_back(i + nums[i]);// index保存最远可跳达的下标。若当前在i处 已知最远可以跳到下标为 index[i]处,则比较其与farthest大小。 直到farthest >= 最大下标,说明可以跳至终点。
}
int jump = 0;
int farthest = index[0];
while (jump < index.size() && jump <= farthest) {
if(farthest < index[jump]){// jump是从0开始往后扫描。 index[jump]是当前最远能到达的下标(i + nums[i])
farthest = index[jump];// 若当前可以跳的更远,则更新farthest
}
jump++;
}
if(jump == index.size()){
return true;
}
return false;
}
};
//int main()
//{
// vector<int> nums;
// nums.push_back(2);
// nums.push_back(3);
// nums.push_back(1);
// nums.push_back(1);
// nums.push_back(4);
// JumpGame jg;
// cout << jg.canJump(nums) << endl;
// return 0;
//}
class JumpGameV2 {
public:
bool canJump(vector<int> A) {
int tmpMax = 0;
int n = A.size();
for (int i = 0; i < n; i++) {
if (i > tmpMax) return false;
if (tmpMax < i + A[i])
tmpMax = i + A[i];
}
return true;
}
};