题目分析
1. Jump Game I和 Jump Game II放在一起做。
2. 一开始还考虑是不是要用动态规划来解答,因为看上去非常像是要动态规划的,但是后来考虑觉得用贪心的思路来做就可以了。我觉得关键是这题走到k之后从[k, k + w[k]]都是可行的路径了,因此只需要一直不断向前贪心就可以了,但是如果考虑问题变成从[k + min[k], k + max[k]]即中间有可能存在空隙的可能就需要用动态规划来求解了,有点类似于NOIP题目校门外的树。
3. 因此直接用贪心来求解,从0一直扫的max,如果当前k + w[k] > max将max置为k + w[k],如果max能够大于或等于最后一个节点则判断可达。
4. 第二题在第一题的基础上也不是特别复杂,只需要记录一下到[前一个最远点,当前最远点区间]是由谁跳过来,或者只需要记录经过多少跳即可。
class Solution {
public:
bool canJump(vector<int>& nums) {
int max = nums[0] - 1;
int i = 0;
while (i == 0 || i <= max) {
if (i + nums[i] > max) max = i + nums[i];
if (max >= nums.size() - 1) return true;
i++;
}
return false;
}
};
class Solution {
public:
int jump(vector<int>& nums) {
vector<int> f(nums.size(), INT_MAX);
f[0] = 0;
int max = 0;
int i = 0;
while (i == 0 || i <= max) {
if (i + nums[i] > max) {
for (int j = max; j <= i + nums[i] && j < nums.size(); j++)
if (f[j] > f[i] + 1) f[j] = f[i] + 1;
max = i + nums[i];
}
i++;
if (i == nums.size()) break;
}
return f[nums.size() - 1];
}
};