赞
踩
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
示例 2:输入: [3,2,1,0,4]
输出: false
解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/jump-game
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我们先用动态规划来求解:
我们维护一个dp数组表示当前位置能到达的最远位置。当dp[i-1] 的值大于 nums.size()-1时,表示我们可以到达数组最大下标。
那么dp数组的更新过程:
- for(int i = 1;i < nums.size();i ++){
- if(dp[i-1] >= nums.size()-1) return true; //i-1位置已经可以跳到数组的最后一个位置,返回true
- //i-1位置可以到达i,那么继续向前,并且dp[i]取i-1位置可以达到的最远距离和i位置加上nums[i]的步长可以达到的最远距离的最值
- if(i <= dp[i-1]) dp[i] = max(dp[i-1],i + nums[i]);
- else break; //i-1位置到达不了i,跳出循环
完整代码:
- class Solution {
- public:
- bool canJump(vector<int>& nums) {
- if(nums.size() == 1) return true; //出道即巅峰
- vector<int> dp(nums.size()); //dp数组表示当前位置可以达到的最远位置
- dp[0] = nums[0]; //0位置的最大长度
- for(int i = 1;i < nums.size();i ++){
- if(dp[i-1] >= nums.size()-1) return true;
- if(i <= dp[i-1]) dp[i] = max(dp[i-1],i + nums[i]);
- else break; //i-1位置到达不了i,跳出循环
- }
- return false; //不能到达最后一个位置
- }
- };
很清晰的动态规划思路,时间复杂度o(n),空间复杂度o(n),运行结果:
紧接着我们进行优化,既然dp[i]状态之和dp[i-1]有关,那么我们只需要维持一个变量表示dp[i-1]就行。
这也就是贪心算法的一个应用了,只观察当前的位置能不能由上一个位置到达。
- class Solution {
- public:
- bool canJump(vector<int>& nums) {
- int rightMost = 0;
- for(int i = 0;i < nums.size();i ++){
- if(rightMost >= nums.size()-1) return true; //已经可以到达数组最后一位
- if(i <= rightMost) rightMost = max(rightMost,i+nums[i]); //更新最远距离
- else break; //中途失败
- }
- return false;
- }
- };
短小精悍,空间复杂度降到o(1)。
继续再发挥一点人类才智:
不到达的情况就是有一个位置的跳数为0,那么我们从后往前找到一个跳数为0的点,然后寻找它前面有没有可以跳过这个位置到达下一个位置的点。
- class Solution {
- public:
- bool canJump(vector<int>& nums) {
- if(nums.size() == 1) return true; //出道即巅峰
- for(int i = nums.size()-2;i >= 0;i --){ //从倒数第二个位置开始遍历
- if(nums[i] == 0){ //该位置跳数为0
- int k;
- for(k = i-1;k >= 0;k --) if(nums[k] > i - k) break; //从k起跳可以避免跳到i
- if(k == -1) return false; //没有找到可以跳过i的位置
- }
- }
- return true;
- }
- };
可以想象最后一种一定是最快的,所以贪心算法套路不固定,所以使用范围有限,当它的时间复杂度能比动态规划更优时,使用意义最大。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。