55. Jump Game
这段话很好
跟着答案走
动态规划
首先,确定网格中最后一个元素可以到达他本身,自上而下,进行判断前一个可以到达他的元素是什么
由此,慢慢的,从后面开始,可以到达最后一块的坐标都被用good填充,这样一来,其他的回溯只需要判断能否到达这些good的点即可,而无需全都走到最后一个
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34enum status {
GOOD,
BAD,
UNKNOW
};
class Solution {
public:
bool canJump(vector<int>& nums) {
dp = new status[nums.size()];
fill(dp, dp + nums.size(), UNKNOW);
dp[nums.size() - 1] = GOOD;
return backTrack(nums, 0);
}
private:
status* dp;
bool backTrack(vector<int>& nums, int start)
{
if(dp[start] != UNKNOW)
return dp[start] == GOOD;
int maxPos = (start + nums[start] > nums.size() - 1) ? nums.size() - 1 : start + nums[start];
for(int pos = start + 1; pos <= maxPos; ++pos)
{
if(backTrack(nums, pos))
{
dp[start] = GOOD;
return true;
}
}
dp[start] = BAD;
return false;
}
};
S(n) : O(n)
bottom Up
从最后出发,判断前一步可不可以走到一个good,依次回去。
1 | enum status |
T(n) : O(n^2)
S(n) : O(n)
greedy
对于一路上的所有good,我能走到右边的就能走到左边的一个good,因此 只需要记录最左边的一个的坐标,空间复杂度降为O(1)
1 | class Solution { |
T(n) : O(n)
S(n) : O(1)
更greedy
1 | class Solution { |
每步都贪,贪不了了就停了
review 1
2
3
4
5
6
7
8
9
10
11
12
13class Solution {
public:
bool canJump(vector<int>& nums) {
int farest = 0;
for(int i = 0, sz = nums.size(); i < sz; ++i)
{
if(farest < i)
return false;
farest = max(farest, i + nums[i]);
}
return true;
}
};