leetcode 45. 跳跃游戏 II

120 阅读2分钟

1. 题目与解析

给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]

每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:

  • 0 <= j <= nums[i] 
  • i + j < n

返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]

输入: nums = [2,3,0,1,4]

输出: 2

输入: nums = [2,3,1,1,4]

输出: 2

解释: 跳到最后一个位置的最小跳跃数是 2。   从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

提示:

  • 1 <= nums.length <= 104
  • 0 <= nums[i] <= 1000
  • 题目保证可以到达 nums[n-1]

我们的目标是到达数组的最后一个位置,因此我们可以考虑最后一步跳跃前所在的位置,该位置通过跳跃能够到达最后一个位置。

求到达 nums[n - 1] 的最小跳跃次数,和跳楼梯的逻辑很像,不同一点是,在这道中,青蛙位于i位置时,可以移动到多个位置而不是1个位置,不过整体的解题思路无伤大雅,是典型的动态规划题目,dp[i]位置有可能移动到dp[i+1]到dp[i+nums[i]],状态转移的方式是加一。

需要注意的一点是,在进行状态转移遍历判断的过程中可能出现数组越界的情况,即i+nums[i]又肯大于n,针对这种情况,需要进行约束,不然会产生数组越界的报错,如下所示:

            for (int j = i+1; j < n && j <= i+nums[i]; j++) {
                dp[j] = Math.min(dp[j], dp[i]+1);
            }

2. 题解

class Solution {
    public int jump(int[] nums) {
        int n = nums.length;
        int[] dp = new int[n];
        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[0] = 0;

        for (int i = 0; i < n-1; i++) {
            for (int j = i+1; j < n && j <= i+nums[i]; j++) {
                dp[j] = Math.min(dp[j], dp[i]+1);
            }
        }

        return dp[n-1];

    }
}