45. 跳跃游戏 II
题目
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
示例:
输入: [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/jump-game-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解思路
1>源代码
# 贪心
class Solution:
def jump(self, nums: List[int]) -> int:
n = len(nums)
steps = 0
maxpos = 0
end = 0
for i in range(n-1):
if maxpos>=i:
maxpos = max(maxpos, nums[i]+i)
if i==end:
steps += 1
end = maxpos
return steps
# 超时
class Solution:
def jump(self, nums: List[int]) -> int:
n = len(nums)-1
steps = 0
while n>0:
for i in range(n):
if i+nums[i]>=n:
steps += 1
n = i
break
return steps
2>算法介绍
本题是一道贪心算法的题目,但在初见此题的时候我想到的是使用暴力方法来解题。即从最后一个元素开始计算,每次在当前元素的前面找到能跳到当前位置的最远元素,例如:
[2,3,1,1,4]
最后一个元素为4(nums[4]),在4之前能跳到最后一个元素位置分别有nums[1]和nums[3],我们需要找到最远的即为nums[1]。
这种方法时间复杂度为O(n^2),在本题中会超时。
本题的另一种方法十分巧妙,仍然是使用贪心算法的思想,举例说明:
[2,3,1,1,4]
对于第一个元素来说,nums[0]可以到达的位置为nums[1]和nums[2],而nums[1]最远可以到达nums[4],nums[2]最远可以到达nums[3],所以我们就选择nums[1]。
对于后续步骤也同上可得,所以本例的跳跃为nums[0]->nums[1]->nums[4]。有了这个思路,我们就可以将本题的时间复杂度优化到O(n)。
然而本题最最巧妙的并不是算法,而是这个算法的实现。具体实现详见代码。