python 贪心算法 动态规划实现 跳跃游戏ll【力扣题45】

简介: python 贪心算法 动态规划实现 跳跃游戏ll【力扣题45】

作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。

会一些的技术:数据分析、算法、SQL、大数据相关、python

欢迎加入社区:码上找工作

作者专栏每日更新:

LeetCode解锁1000题: 打怪升级之旅

python数据分析可视化:企业实战案例

备注说明:方便大家阅读,统一使用python,带必要注释,公众号 数据分析螺丝钉 一起打怪升级

题目描述

LeetCode 题目 45:跳跃游戏 II

题目描述

给定一个非负整数数组 nums,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度(如果值是2则可以选择0、1、2进行跳跃 最大不超过2)。你的目标是使用最少的跳跃次数到达数组的最后一个位置。

输入格式
  • nums:一个非负整数数组。
输出格式
  • 返回到达数组最后一个位置的最小跳跃次数。

示例

示例 1
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
     从索引 0 跳到索引 1 的位置,跳1步,然后从索引 1 跳到索引 4,跳3步。
示例 2
输入: nums = [2,3,0,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
     从索引 0 跳到索引 1 的位置,跳1步,然后从索引 1 跳到索引 4,跳3步。

功能和约束

  • 数组 nums 的长度不超过 10^4。
  • 每个元素的大小不超过 1000。
  • 你可以假设总是可以到达数组的最后一个位置。

这个问题要求找到一个高效的方法来确定达到数组末尾的最少跳跃次数。我们可以通过不同的策略来解决这个问题,包括动态规划、贪心算法等,来尽可能地减少计算时间和空间消耗。

方法一:贪心算法(正向)

解题步骤
  1. 初始化变量
  • end 表示当前能跳到的最远边界。
  • farthest 表示所有可选择跳的位置中,能跳到的最远位置。
  • jumps 记录跳跃次数。
  1. 遍历数组:除了最后一个元素,因为一旦到达最后一个元素,不需要再跳跃。
  • 更新能跳到的最远位置 farthest
  • 如果到达了当前的 end,即边界,更新边界并增加跳跃次数。
  1. 返回跳跃次数
完整代码
def jump(nums):
    """
    使用贪心算法从前向后计算最少的跳跃次数
    :param nums: List[int], 每个位置可以跳跃的最大长度
    :return: int, 最少跳跃次数
    """
    n = len(nums)
    end = farthest = jumps = 0
    
    for i in range(n - 1):  # 最后一个元素不需要访问
        farthest = max(farthest, i + nums[i])  # 更新能到达的最远位置
        if i == end:  # 到达上一跳能到的边界了
            jumps += 1  # 增加跳跃次数
            end = farthest  # 更新边界为当前能到达的最远位置
            if end >= n - 1:  # 如果已经能跳到最后位置
                break
    
    return jumps
# 示例调用
print(jump([2, 3, 1, 1, 4]))  # 输出: 2
算法分析
  • 时间复杂度:(O(N)),其中 (N) 是数组长度。
  • 空间复杂度:(O(1)),使用了有限的额外空间。

方法二:动态规划

解题步骤
  1. 初始化数组:创建一个数组 dp,其中 dp[i] 表示到达第 i 个位置的最少跳跃次数。
  2. 填充数组:初始化一个非常大的数表示无法到达的位置。
  3. 逐步更新:对于每个位置,尝试通过之前的所有位置跳到当前位置,更新 dp[i]
  4. 返回结果dp[n-1] 即为到达最后位置的最少跳跃次数。
完整代码
def jump(nums):
    """
    使用动态规划计算到达最后位置的最少跳跃次数
    :param nums: List[int], 每个位置可以跳跃的最大长度
    :return: int, 最少跳跃次数
    """
    n = len(nums)
    dp = [float('inf')] * n
    dp[0] = 0
    
    for i in range(1, n):
        for j in range(i):
            if j + nums[j] >= i:
                dp[i] = min(dp[i], dp[j] + 1)
    
    return dp[-1]
# 示例调用
print(jump([2, 3, 1, 1, 4]))  # 输出: 2
算法分析
  • 时间复杂度:(O(N^2)),其中 (N) 是数组长度,每个元素需被重复访问和比较。
  • 空间复杂度:(O(N)),使用了一个与输入数组等长的 dp 数组。

方法三:贪心算法(反向)

解题步骤
  1. 初始化指针:从数组最后一个位置开始。
  2. 逆向查找:寻找最远可以一步跳到当前位置的起点。
  3. 更新位置:更新当前位置到找到的位置,增加跳跃次数。
  4. 重复执行:直到到达数组的开始位置。
完整代码
def jump(nums):
    """
    使用贪心算法从后向前计算最少的跳跃次数
    :param nums: List[int], 每个位置可以跳跃的最大长度
    :return: int, 最少跳跃次数
    """
    position = len(nums) - 1
    steps = 0
    
    while position > 0:
        for i in range(position):
            if i + nums[i] >= position:
                position = i
                steps += 1
                break
    
    return steps
# 示例调用
print(jump([2, 3, 1, 1, 4]))  # 输出: 2
算法分析
  • 时间复杂度:(O(N^2)),虽然是贪心算法,但在最坏情况下退化成平方级别的时间复杂度。
  • 空间复杂度:(O(1)),只使用了常数空间。

总结

下面的表格将展示它们在不同技术维度的性能和特点,包括时间复杂度、空间复杂度以及各自的优势和劣势。

特征 方法一:正向贪心算法 方法二:动态规划 方法三:反向贪心算法
时间复杂度 (O(N)) (O(N^2)) (O(N^2))
空间复杂度 (O(1)) (O(N)) (O(1))
优势 - 高效且直接
- 实现简单
- 理论上全面
- 易于理解和实现
- 无需预先知道全局信息
- 实现简单
劣势 - 需要合理选择跳跃策略 - 空间和时间消耗大
- 不适合大规模数据
- 时间复杂度高
- 可能多次迭代寻找最优点
适用场景 - 大规模数据
- 需要最优时间性能
- 数据规模较小
- 对执行时间要求不高
- 理解问题的另一种方式
- 数据规模较小

综合分析

方法一(正向贪心算法)

  • 这种方法通过从前往后贪心地选择每一跳的最远可达点,以最小化跳跃次数。其时间复杂度为线性,是解决此问题的最高效方法。适用于大规模数据,因为其空间复杂度极低。

方法二(动态规划)

  • 动态规划提供了一种全面检查所有可能性的方法,通过构建一个状态转移表来决定最少的跳跃次数。虽然这种方法在小规模数据上表现良好,但在大规模数据处理上由于其平方级时间复杂度表现不佳。

方法三(反向贪心算法)

  • 反向贪心算法从数组的末端开始向前搜索,寻找能到达末端的最远起点,然后逐步逆向缩减问题规模。这种方法的优点是实现简单,但与正向贪心算法相比,其效率较低,因为它在最坏情况下的时间复杂度也是平方级。

在选择合适的算法时,应根据具体的应用需求和问题规模做出决策。对于大规模的实际应用,正向贪心算法通常是最优的选择,因为它提供了最好的时间和空间效率。对于教学或者问题规模较小的场合,可以考虑动态规划或反向贪心算法,以便更好地理解问题的结构。


欢迎关注微信公众号 数据分析螺丝钉

相关文章
|
6月前
|
算法 搜索推荐 JavaScript
基于python智能推荐算法的全屋定制系统
本研究聚焦基于智能推荐算法的全屋定制平台网站设计,旨在解决消费者在个性化定制中面临的选择难题。通过整合Django、Vue、Python与MySQL等技术,构建集家装设计、材料推荐、家具搭配于一体的一站式智能服务平台,提升用户体验与行业数字化水平。
|
7月前
|
存储 算法 调度
【复现】【遗传算法】考虑储能和可再生能源消纳责任制的售电公司购售电策略(Python代码实现)
【复现】【遗传算法】考虑储能和可再生能源消纳责任制的售电公司购售电策略(Python代码实现)
358 26
|
6月前
|
存储 监控 算法
监控电脑屏幕的帧数据检索 Python 语言算法
针对监控电脑屏幕场景,本文提出基于哈希表的帧数据高效检索方案。利用时间戳作键,实现O(1)级查询与去重,结合链式地址法支持多条件检索,并通过Python实现插入、查询、删除操作。测试表明,相较传统列表,检索速度提升80%以上,存储减少15%,具备高实时性与可扩展性,适用于大规模屏幕监控系统。
211 5
|
7月前
|
机器学习/深度学习 存储 算法
动态规划算法深度解析:0-1背包问题
0-1背包问题是经典的组合优化问题,目标是在给定物品重量和价值及背包容量限制下,选取物品使得总价值最大化且每个物品仅能被选一次。该问题通常采用动态规划方法解决,通过构建二维状态表dp[i][j]记录前i个物品在容量j时的最大价值,利用状态转移方程避免重复计算子问题,从而高效求解最优解。
829 1
|
7月前
|
机器学习/深度学习 编解码 算法
【机器人路径规划】基于迪杰斯特拉算法(Dijkstra)的机器人路径规划(Python代码实现)
【机器人路径规划】基于迪杰斯特拉算法(Dijkstra)的机器人路径规划(Python代码实现)
590 4
|
7月前
|
机器学习/深度学习 算法 机器人
【机器人路径规划】基于A*算法的机器人路径规划研究(Python代码实现)
【机器人路径规划】基于A*算法的机器人路径规划研究(Python代码实现)
953 4
|
7月前
|
算法 机器人 定位技术
【机器人路径规划】基于流场寻路算法(Flow Field Pathfinding)的机器人路径规划(Python代码实现)
【机器人路径规划】基于流场寻路算法(Flow Field Pathfinding)的机器人路径规划(Python代码实现)
481 4
|
6月前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
7月前
|
机器学习/深度学习 算法 机器人
【机器人路径规划】基于深度优先搜索(Depth-First-Search,DFS)算法的机器人路径规划(Python代码实现)
【机器人路径规划】基于深度优先搜索(Depth-First-Search,DFS)算法的机器人路径规划(Python代码实现)
380 3
|
7月前
|
机器学习/深度学习 算法 机器人
【机器人路径规划】基于D*算法的机器人路径规划(Python代码实现)
【机器人路径规划】基于D*算法的机器人路径规划(Python代码实现)
355 0

推荐镜像

更多