Leetcode Algorithm 055. Jump Game
Jump Game
给定一个非负整数的数组,数组中的元素表示从当前位置可以跳过的最长步数;判断从数组的第一个位置,能否跳到最后一个位置
解题思路
先看看题目给出的样例1:
A = [2,3,1,1,4]
可以先判断A[3]能否到达A[4],最少的代价是1步跳跃;
假如A[3]>=1,说明A[3]可达A[4],往前判断A[2]能否到达A[3],最少的代价是1步跳跃;否则,可以往前判断A[2]能否到达A[4],最少的代价是2步跳跃;
这个样例中,A[3]可达A[4],A[2]可达A[3],A[1]可达A[2],A[0]可达A[1],我们可以找出一跳最长链,也说明无论从哪一点出发A[4]均可达。
样例2:
A = [3,2,1,0,4]
这个样例中,A[3]不可达A[4],A[2]不可达A[4],A[1]不可达A[4],A[0]不可达A[4],也就是说,无论从哪一点出发A[4]均不可达,所以不存在。
再看一个样例3
A = [2,3,0,1,4]
这个样例中,A[3]可达A[4],A[2]不可达A[3],但A[1]可达A[3],A[0]可达A[1],我们也可以找出一跳最长链,除了A[2],从其余的点出发A[4]均可达。
这里采用的是一个贪心策略,每次只判断离目标点最近的点有没有直接可达的,如果有则更新目标点。这样的话,扫描一遍数组就可以得出结果,时间复杂度为O(n),但总的跳跃的次数是最坏次数。
代码
#include<iostream>
#include<vector>
using namespace std;
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size();
int step = 1;
bool flag = true;
for (int i = n - 2; i >= 0; i--) {
if (nums[i] >= step)
step = 1;
else {
if (i != 0) {
step++;
} else {
flag = false;
}
}
}
return flag;
}
};
测试样例与输出
struct TestCase {
vector<int> nums;
};
int main() {
int numTestCase = 2;
TestCase tCase[numTestCase];
int arr0[] = { 2, 3, 1, 1, 4 };
tCase[0].nums.assign(arr0, arr0 + 5);
int arr1[] = { 3, 2, 1, 0, 4 };
tCase[1].nums.assign(arr1, arr1 + 5);
Solution s;
for (int t = 0; t < numTestCase; t++) {
string result = s.canJump(tCase[t].nums) ? "true" : "false";
cout << result << endl;
}
return 0;
}
输出
true
false