LeetCode 45. Jump Game II 跳跃游戏II,求最少跳跃次数 (贪心)

匿名 (未验证) 提交于 2019-12-03 00:30:01

https://leetcode.com/problems/jump-game-ii/description/

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

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

你的目标是使用最少的跳跃次数到达数组的最后一个位置。

示例:
输入: [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

说明:
假设你总是可以到达数组的最后一个位置。

题解:
跳跃问题1 中求能否到达最后位置,用一个 reach 变量 记录能够到达的最远的下标,每走一步比较更新该值,到达最终位置前,如果当前下标大于reach,说明失败。如果能到达最后,说明成功。

而这道题,需要求的是最少的步数。因此需要添加 count 变量记录最少步数。什么时候 count++ 是问题的关键?答案是当前的位置 i 超过了上一跳所能到达的最远位置。所以需要引入变量 last 记录上一跳可达最远坐标。此题代码在跳跃问题1 代码基础上修改。

class Solution {     public int jump(int[] nums) {         if (nums == null || nums.length == 0) {             return -1;         }         int reach = 0;//当前所能到达的最远坐标         int last = 0;//上一跳可达最远坐标         int count = 0;//跳跃次数         for (int i = 0; i < nums.length; i++) {             if (i > reach) {                 return -1;             }             if (i > last) {                 count++;                 last = reach;             }             if (i + nums[i] > reach) {                 reach = i + nums[i];             }         }         return count;     } }

动态规划解法:
复杂度是 O(n2),会超时,但是依然需要掌握。

定义状态:dp[i] 表示到达 i 位置的最小跳数
起始装填:dp[0]=0 到达下标0的最小跳数是0
终止状态:dp[nums.length-1] 即到达最后一个位置的最小跳数
决策:选择 i 之前的能跳到 i 的所有位置j 中, dp[j] 值最小的位置 j 作为上一步要跳到 i 的位置
费用表示:dp[i]=dp[j]+1 ,从 j 跳到 i ,步数加1
无后效性:收益1 是个常数,不随状态改变

class Solution {     public int jump(int[] nums) {         int[] dp = new int[nums.length];//dp[i] 为到达 i 位置的最小跳数         dp[0] = 0;//到达下标0的最小跳数是0         for (int i = 1; i < nums.length; i++) {             dp[i] = Integer.MAX_VALUE;             for (int j = 0; j < i; j++) {                 if (i - j <= nums[j]) {                     dp[i] = Math.min(dp[i], dp[j] + 1);                 }             }         }         return dp[nums.length - 1];     } }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!