[LeetCode] #45 跳跃游戏 II
给你一个非负整数数组 nums ,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
使用最少的跳跃次数很容易可以想到用贪心算法或者动态规划
贪心算法有两种思路
一是贪开始的每一步,二是贪最后一步
贪心算法一(贪开始的每一步)
以[2,3,1,1,4]为例,
位于0下标位置,可以选择到1下标、2下标,最远边界是2(max = 2)
此时必须跳一步(step++,step=1),最远可以跳到2,当我们到达2时又必须选择跳下一步(end = 2)
位于1下标位置,可以选择到2下标、3下标、4下标,最远边界是4(max = 4)
此时可以先不跳
位于2下标位置,可以选择到3下标,最远边界是3,小于4不更新边界
此时必须跳一步(step++,step=2),最远可以跳到4,当我们到达4时又必须选择跳下一步(end = 4)
。。。。。
class Solution { public int jump(int[] nums) { int l = nums.length; int end = 0; int max = 0; int step = 0; for(int i = 0; i < l - 1; i++){ max = Math.max(max, nums[i] + i); if(i == end){ end = max; step++; } } return step; } }
贪心算法二(贪最后一步)
以[2,3,1,1,4]为例,
位于0下标位置,显然不能跳到最后,不能最为最后一步
位于1下标位置,可以跳到最后,此时与终点最远,直接贪,作为最后一步。确认这一步(step++)之后,更新最后一步(last = i)并且重新开始(break)。
。。。。
当最后一步是起点时结束
class Solution { public int jump(int[] nums) { int step = 0; int last = nums.length - 1; while(last > 0){ for(int i = 0; i < last; i++){ if(nums[i] + i >= last){ last = i; step++; break; } } } return step; } }
动态规划
dp[i]:到达i的最小步数
状态转移方程:dp[i + j] = Math.min(dp[i + j], dp[i] + 1)
class Solution { public int jump(int[] nums) { int[] dp = new int[nums.length]; dp[0] = 0; for (int i = 1; i < dp.length; i++) { dp[i] = nums.length + 1; } for (int i = 0; i < nums.length; i++) { for (int j = 1; j <= nums[i]; j++ ) { if (i + j >= nums.length) { return dp[dp.length - 1]; } dp[i + j] = Math.min(dp[i + j], dp[i] + 1); } } return dp[dp.length - 1]; } }
知识点:无
总结:无