- lintcode:
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.
Example
A = [2,3,1,1,4], return true.
A = [3,2,1,0,4], return false.
- State: f[i] 从起点出发能否达到i
- Function:
f[i] = OR (f[j], j < i ~\&\&~ j + A[j] \geq i)
, 状态$$j$$ 转移到$$i$$ , 所有小于i的下标j的元素中是否存在能从j跳转到i得 - Initialization: f[0] = true;
- Answer: 递推到第 N - 1 个元素时,f[N-1]
这种自顶向下的方法需要使用额外的
class Solution {
public:
/**
* @param A: A list of integers
* @return: The boolean answer
*/
bool canJump(vector<int> A) {
if (A.empty()) {
return true;
}
vector<bool> jumpto(A.size(), false);
jumpto[0] = true;
for (int i = 1; i != A.size(); ++i) {
for (int j = i - 1; j >= 0; --j) {
if (jumpto[j] && (j + A[j] >= i)) {
jumpto[i] = true;
break;
}
}
}
return jumpto[A.size() - 1];
}
};
题意为问是否能从起始位置到达最终位置,我们首先分析到达最终位置的条件,从坐标i出发所能到达最远的位置为
以下分析形式虽为动态规划,实则贪心法!
- State: f[i] 从
$$i$$ 出发能否到达最终位置 - Function:
$$f[j] = j + A[j] \geq i$$ , 状态$$j$$ 转移到$$i$$ , 置为true
- Initialization: 第一个为
true
的元素为A.size() - 1
- Answer: 递推到第 0 个元素时,若其值为
true
返回true
class Solution {
public:
/**
* @param A: A list of integers
* @return: The boolean answer
*/
bool canJump(vector<int> A) {
if (A.empty()) {
return true;
}
int index_true = A.size() - 1;
for (int i = A.size() - 1; i >= 0; --i) {
if (i + A[i] >= index_true) {
index_true = i;
}
}
return 0 == index_true ? true : false;
}
};
针对上述自顶向下可能出现时间复杂度过高的情况,下面使用贪心思想对i进行递推,每次遍历A中的一个元素时更新最远可能到达的元素,最后判断最远可能到达的元素是否大于 A.size() - 1
class Solution {
public:
/**
* @param A: A list of integers
* @return: The boolean answer
*/
bool canJump(vector<int> A) {
if (A.empty()) {
return true;
}
int farthest = A[0];
for (int i = 1; i != A.size(); ++i) {
if ((i <= farthest) && (i + A[i] > farthest)) {
farthest = i + A[i];
}
}
return farthest >= A.size() - 1;
}
};