您的位置:首页 > 其它

leetcode55_跳跃游戏

2019-10-05 10:31 113 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qieyuan4083/article/details/102134624

一. 首先放上自己的代码,是用的动态规划的思路.动态规划的关键和递归一样,都需要明确dp函数的含义.

[code]//动态规划,dp[i]含义为能否到达以i结尾的那个数.
class Solution {
public:
bool canJump(vector<int>& nums) {
int len = nums.size();
vector<int> dp(len, 0);
//初始条件,一定可以到达第一个位置,因为初始就在第一个位置.
dp[0] = 1;
for (int i = 1; i < len; i++) {
for (int num = i - 1; num >= 0; num--) {
//找到可以跳跃到i的最近的点.
if (nums[num] + num >= i) {
//在小于i的索引中,只要有一个num
//可以到达i就算能到达.
dp[i] = dp[i] + dp[num];
if (dp[i] > 0)
//如果所有情况加起来大于0
//表示可以到达,则退出.
break;
}
}
if (dp[i] > 0)
dp[i] = 1;
}
return dp[len - 1];
}
};

二.  再来参考一下题解.

作者:ikaruga
链接:https://leetcode-cn.com/problems/jump-game/solution/55-by-ikaruga/

思路
1.  如果某一个作为起跳点的格子可以跳跃的距离是3,那么表示后面3个格子都可以作为起跳点。
2.  可以对每一个能作为起跳点的格子都尝试跳一次,把能跳到最远的距离不断更新。
3.  如果可以一直跳到最后,就成功了。

[code]class Solution {
public:
bool canJump(vector<int>& nums)
{
int k = 0;
for (int i = 0; i < nums.size(); i++)
{
//如果跳不到,则失败.
if (i > k) return false;
//更新当前可以跳到的最大距离.
k = max(k, i + nums[i]);
}
return true;
}
};

三.  参考下一个题解

作者:yangtianrui95
链接:https://leetcode-cn.com/problems/jump-game/solution/dong-tai-gui-hua-yu-tan-xin-suan-fa-jie-jue-ci-wen/

1.  这个题我们可以从后往前分析,首先判断倒数第二个元素能否到达最后一个元素,如果可以,我们将不再考虑最后一个元素,
因为根据刚才的分析如果可以到达倒数第二个,那么也可以到达最后一个元素。

然后依次往前递推,如果都能跳到的话,我们最后应该分析的就是第一个元素能否跳到第二个元素上。

这个比较符合动态规划的思想,我们先用动态规划解下这道题。

[code]//改进的动态规划,dp[i]含义为能否到达以i结尾的那个数.
class Solution {
public:
bool canJump(vector<int>& nums) {
int len = nums.size();
vector<int> dp(len, 0);
//初始条件,一定可以到达第一个位置,因为初始就在第一个位置.
dp[0] = 1;
for (int i = 1; i < len; i++) {
for (int num = i - 1; num >= 0; num--) {
//如果dp[num]为1并且可以到达i,
//则dp[i]一定能到达.
if (dp[num] && nums[num] + num >= i) {
dp[i] = 1;
//如果是1,则直接break了.
break;
}
}
}
return dp[len - 1];
}
};

2.  下面我们使用贪心的思路看下这个问题,我们记录坐标代表当前可达的最后节点,这个坐标初始等于nums.length-1,
然后我们每判断完是否可达,都向前移动这个坐标,直到遍历结束。如果这个坐标等于0,那么认为可达,否则不可达。

[code]//贪心思想
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size();
int last = n - 1;
for (int i = last - 1; i >= 0; i--) {
if (nums[i] + i >= last) {
last = i;
}
}
return last == 0;
}
};

这段代码的时间复杂度是O(n),空间复杂度是O(1),可以看出比动态规划解法有了明显的性能提升。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: