【leedcode】45. 跳跃游戏 II

322 阅读1分钟

这是我参与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]