给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标。

示例 1:
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

思路:
只求结果,考虑动态规划。
dp[i]表示第i步是否可抵达 dp[i]=dp[j]&&(nums[j]>=i-j)
第i步可以抵达的条件:

  1. 在之前的第j步可以抵达=dp[j]为true
  2. 第j步可以达到第i步,(nums[j]>=i-j),第j步可迈的长度大于等于i和j之间的距离
class Solution {
public:
    bool canJump(vector<int>& nums) {
        //方程:dp[i]=dp[j]&&(nums[j]>=i-j)
        vector<bool> dp(nums.size(),false);
        dp[0]=true;
        for(int i=1;i<nums.size();i++){
            for(int j=i-1;j>=0;j--){//第i步之前的状态
                dp[i]=dp[j]&&(nums[j]>=i-j);
                if(dp[i]) break;
            }
        }
        return dp[nums.size()-1];
    } 
};

复杂度高,更好的解法,贪心算法
站在某点,它可以到达的最远距离是i+nums[i];
所以从0开始,每次计算它可以到达的最远距离mixdist,并且更新mixdist
同时,还需要提前判断该点是否在当前的mixdist范围内

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int maxdist=0;
        for(int i=0;i<nums.size();i++){
            if(i<=maxdist){//是否在最大范围内
                maxdist=max(maxdist,i+nums[i]);//更新最大距离
            }
        }
        return maxdist>=nums.size()-1;//最大距离是否包括最后一个点的位置
    } 
};