这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战
难度:中等
问题描述
给你一个非负整数数组 nums ,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。
示例 1:
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
示例 2:
输入: nums = [2,3,0,1,4]
输出: 2
提示:
1 <= nums.length <= 104
0 <= nums[i] <= 1000
这里给出两种解题方法(贪心算法&动态规划)
个人感觉第二种算法更适合新手
方法一 贪心算法:
解题思路:
这道题为什么能用贪心算法呢? 因为每一步的最大下一跳的数,一定包含其他的数,因为它跳的最远,也就是涵盖了所有结果,保证了真确性,没有遗漏!
代码:
class Solution:
def jump(self, nums: List[int]) -> int:
""" 贪心算法 """
n = len(nums)
step = 0
left, right, cur = 0, 0, 0
# 当元素个数为1 直接返回
if len(nums) == 1:
return 0
# 循环
while left < n:
# 1. 每次更新当前元素的 left, right
left = right + 1
right = cur + nums[cur]
# 如果 right 值大于 n-1了,说明下一步一定能到,返回
if right >= n-1:
return step + 1
# 根据贪心算法,找到能走的最远的 下一个元素
temp = 0
for i in range(left, right+1):
if i + nums[i] > temp:
temp = i + nums[i]
cur = i
step += 1
方法二(动态规划):
解题思路:
1.首先初始化nums数组,默认不跳,每个格子的走的次数就是它的下标
2.每到一个格子,更新它所有能到的格子的下标,如果比原来存储的少,则替换
class Solution(object):
def jump(self, nums):
res = [i for i in range(len(nums))]
for i in range(len(nums)):
# temp =i(现在位置的坐标)+nums[i](能飞的最大距离)
temp = i+nums[i]
# 每个位置更新一遍
for j in range(i,temp+1):
if j<len(nums):
res[j]=min(res[j],res[i]+1)
return res[-1]