LeetCode 45. 跳跃游戏 II(难)
贪心算法的三个步骤
第一步、明确到底什么是最优解?
第二步、明确什么是子问题的最优解?(子问题的最优解有很多,选择一个最直接、最容易理解的方式进行定义即可。)
第三步、分别求出子问题的最优解再堆叠出全局最优解。
题目
给定一个非负整数数组,你最初位于数组的第一个位置。 数组中的每个元素代表你在该位置可以跳跃的最大长度,但是你不一定要这么跳。 你的目标是使用最少的跳跃次数到达数组的最后一个位置。
说明: 假设你总是可以到达数组的最后一个位置。
示例
示例: 1
2输入: [2,3,1,1,4]
输出: 2
考察知识点
贪心算法
核心思想
方法一、贪心算法
贪心算法的三个步骤
第一步、明确到底什么是最优解?
第二步、明确什么是子问题的最优解?(子问题的最优解有很多,选择一个最直接、最容易理解的方式进行定义即可。)
第三步、分别求出子问题的最优解再堆叠出全局最优解。
本问题的三个步骤
第一步、最优解:使用最少的步数到达最后一个位置。
第二步、子问题最优解:在第i
步走最远的距离。
第三步、分别求出子问题的最优解再堆叠出全局最优解:计算每一步的结果,当累积距离等于或者超出终点时,结束运算,返回执行跳跃的次数,就是最小步数。
算法步骤
- 定义步数
step=0
,能达到的最远位置max_bound=0
,和上一步到达的边界end=0
。 - 遍历数组,遍历范围
[0,n-1)
:- 所能达到的最远位置
max_bound=max(max_bound,nums[i]+i)
,表示上一最远位置和当前索引i
和索引i
上的步数之和中的较大者,作为新的最远距离,如果上次跳跃的最远距离比在这里跳跃还远(max_bound > nums[i]+i
),那就继续上次的跳跃。 - 如果索引
i
到达了上一步的边界end
,即i==end
,则更新边界end
,令end
等于新的最远边界max_bound
,即end=max_bound
,令步数step
加 1。
- 所能达到的最远位置
- 返回step 注意! 数组遍历范围为
[0,n-1)
,因为当i==0
时,step
已经加一,所以若最后一个元素也遍历的话,当end
恰好为n-1
,步数会多1。
Python版本
方法一的实现
1 |
|
时间复杂度:O(n)
空间复杂度:O(1)
执行用时 :52 ms, 在所有 Python3 提交中击败了97.36%的用户
内存消耗 :14.7 MB, 在所有 Python3 提交中击败了96.65%的用户
输出分析
1 |
|
略作修改
1 |
|
执行用时 :32 ms, 在所有 Python3 提交中击败了100.00%的用户
内存消耗 :14.7 MB, 在所有 Python3 提交中击败了98.23%的用户
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!