87 :Jump Game

本文解析了跳跃游戏问题的三种解法:直接正向遍历、逆向可达性判断及动态规划,并提供了每种方法的代码实现,帮助读者理解并掌握算法核心。

题目: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.
For example:
A = [2,3,1,1,4], return true.
A = [3,2,1,0,4], return false.

解析1:从数组的第一个位置开始往后跳,看看最终能不能跳跃到超过或等于最后一个指针的位置,代码如下:

// 时间复杂度 O(n),空间复杂度 O(1)
// 从数组的第一个位置开始往后跳
class Solution {
public:
        bool canJump(vector<int>& nums) {
                int reach = 0; // 最右能跳到哪里
                int last_index = nums.size() - 1;
                for (int i = 0; i <= reach && reach < last_index; ++i)
                        reach = max(reach, i + nums[i]);

                return reach >= last_index;
        }
};

解析2:从数组最后一个一个位置往前跳,看看能不能跳到数组的第一个位置,代码如下:

// 时间复杂度 O(n),空间复杂度 O(1)
// 从数组的最后一个位置开始往前跳
class Solution {
public:
        bool canJump(vector<int>& nums) {
                if (nums.empty()) return true;
                // 逆向下楼梯,最左能下降到第几层
                int left_most = nums.size() - 1;

                for (int i = nums.size() - 2; i >= 0; --i)
                        if (i + nums[i] >= left_most)
                                left_most = i;

                return left_most == 0;
        }
};

解析3:用动态规划求解,令 f[i] 表示从第 0 层出发走到第 i 层时剩余的最大步数,其满足的递推公式为 f[i]=max(f[i1],nums[i1])+1 。如果到达数组最后一个位置处时最大剩余步数大于 0, 说明是数组最后一个位置是可以到达的,代码如下:

// 时间复杂度 O(n),空间复杂度 O(n)
// 动态规划
class Solution {
public:
        bool canJump(vector<int>& nums) {
                vector<int> f(nums.size(), 0);
                f[0] = 0;
                for (int i = 1; i < nums.size(); ++i) {
                        f[i] = max(f[i - 1], nums[i - 1]) - 1;
                        if (f[i] < 0) return false;
                }
                return f[nums.size() - 1] >= 0;
        }
};

上面代码的思想及编写参考了网址https://github.com/soulmachine/leetcode#leetcode题解题目

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值