力扣刷题笔记《动态规划篇》→ 55. 跳跃游戏

122 阅读2分钟

这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战

题目

给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标。

示例

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

输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

提示

  • 1 <= nums.length <= 3 * 10410^4
  • 0 <= nums[i] <= 10510^5

解题思路

通过题目可以比较直观的看到,元素值nums[i]为当前位置可跳的步数,那么我们可以得出当前位置i的最远可达位置为i + nums[i],由此可得公式为:dp[i] = max(dp[i - 1], i + nums[i])

1.gif

在套用公式的同时,由于我们是要判断能否跳到数组末尾处,那么在中间如果有缺口的话(dp[i - 1] < i),就需要我们再做一个判断来停止推导,否则会导致最终结果失真。

2.gif

代码实现

方式一:动态规划

class Solution {
    public boolean canJump(int[] nums) {
        int n = nums.length;
        // 初始化
        int[] dp = new int[n];
        dp[0] = nums[0];

        for(int i = 1; i < n; ++i){
            // 缺口判断
            if(i > dp[i - 1]){
                return false;
            }
            // 状态转移
            dp[i] = Math.max(i + nums[i], dp[i - 1]);
        }

        // 返回结果
        return dp[n - 1] >= n - 1;
    }
}

复杂度分析

  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(n)O(n)

方式二:动态规划优化

在方式一中我们定义了一个数组,但实际上在状态转移的过程中我们只用到了dp[i - 1]这一个值而已,那么我们可以在这进行一个优化。

class Solution {
    public boolean canJump(int[] nums) {
        int n = nums.length;
        // 最远边界,相当于dp[i - 1]
        int max = nums[0];

        for(int i = 1; i < n - 1; ++i){
            if(i > max){
                return false;
            }
            // 状态转移
            max = Math.max(max, i + nums[i]);
        }

        // 返回结果
        return max >= n - 1;
    }
}

复杂度分析

  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

方式三:倒推法

在一个有限的数组中,边界是确定了的,那么我们除了从前往后遍历,还可以从后往前遍历,进行状态的转移。 从末尾idx开始,往前遍历,前面的元素能否跳到idx处,如果可以,更新idx为当前索引i

class Solution {
    public boolean canJump(int[] nums) {
        int n = nums.length;
        int idx = n - 1;

        for(int i = n - 2; i >= 0; --i){
            // 当前位置可以跳到 idx 处,更新 idx
            if(i + nums[i] >= idx){
                idx = i;
            }
        }

        // 返回结果
        return idx == 0;
    }
}

复杂度分析

  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

最后

文章有写的不好的地方,请大佬们不吝赐教,错误是最能让人成长的,愿我与大佬间的距离逐渐缩短!

如果觉得文章对你有帮助,请 点赞、收藏、关注、评论 一键四连支持,你的支持就是我创作最大的动力!!!

题目出处:leetcode-cn.com/problems/ju…