leetcode题目70:爬楼梯【python】

简介: leetcode题目70:爬楼梯【python】

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

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

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

作者专栏每日更新:

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

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

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

题目描述

假设你正在爬楼梯。需要 n 步你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 将是一个正整数。

输入格式
  • n:一个正整数,表示楼梯的总台阶数。
输出格式
  • 返回一个整数,表示不同的爬楼梯方法数。

示例

示例 1
输入: n = 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1.  1 步 + 1 步
2.  2 步
示例 2
输入: n = 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1.  1 步 + 1 步 + 1 步
2.  1 步 + 2 步
3.  2 步 + 1 步

方法一:动态规划

解题步骤
  1. 定义状态数组dp[i] 表示到达第 i 阶楼梯的方法数。
  2. 初始化dp[0] = 1(不动),dp[1] = 1(一步)。
  3. 状态转移方程dp[i] = dp[i-1] + dp[i-2]
  4. 求解:计算 dp[n]
完整的规范代码
def climbStairs(n):
    """
    使用动态规划解决爬楼梯问题
    :param n: int, 楼梯总步数
    :return: int, 爬到楼顶的方法数
    """
    if n <= 1:
        return 1
    dp = [0] * (n + 1)
    dp[0], dp[1] = 1, 1
    for i in range(2, n + 1):
        dp[i] = dp[i - 1] + dp[i - 2]
    return dp[n]
# 示例调用
print(climbStairs(2))  # 输出: 2
print(climbStairs(3))  # 输出: 3
算法分析
  • 时间复杂度:(O(n)),一次遍历到 n
  • 空间复杂度:(O(n)),用于存储 dp 数组。

方法二:空间优化的动态规划

解题步骤
  1. 利用两个变量滚动更新:只需要两个变量来存储前两步的结果。
  2. 更新变量:迭代更新两个变量来计算下一步的值。
完整的规范代码
def climbStairs(n):
    """
    使用空间优化的动态规划解决爬楼梯问题
    :param n: int, 楼梯总步数
    :return: int, 爬到楼顶的方法数
    """
    if n <= 1:
        return 1
    a, b = 1, 1
    for i in range(2, n + 1):
        a, b = b, a + b
    return b
# 示例调用
print(climbStairs(2))  # 输出: 2
print(climbStairs(3))  # 输出: 3
算法分析
  • 时间复杂度:(O(n))。
  • 空间复杂度:(O(1)),只使用固定的几个变量。

方法三:矩阵快速幂

解题步骤
  1. 定义转移矩阵:使用矩阵快速幂求解斐波那契数列问题。
  2. 矩阵乘法:定义矩阵乘法和矩阵快速幂函数。
完整的规范代码
def climbStairs(n):
    """
    使用矩阵快速幂解决爬楼梯问题
    :param n: int, 楼梯总步数
    :return: int, 爬到楼顶的方法数
    """
    if n <= 1:
        return 1
    
    def multiply(a, b):
        return [[a[0][0] * b[0][0] + a[0][1] * b[1][0], a[0][0] * b[0][1] + a[0][1] * b[1][1]],
                [a[1][0] * b[0][0] + a[1][1] * b[1][0], a[1][0] * b[0][1] + a[1][1] * b[1][1]]]
    def matrix_pow(matrix, power):
        result = [[1, 0], [0, 1]]
        base = matrix
        while power:
            if power % 2:
                result = multiply(result, base)
            base = multiply(base, base)
            power //= 2
        return result
    result = matrix_pow([[1, 1], [1, 0]], n - 1)
    return result[0][0] + result[0][1]
# 示例调用
print(climbStairs(2))  # 输出: 2
print(climbStairs(3))  # 输出: 3
算法分析
  • 时间复杂度:(O(log n)),矩阵快速幂的时间复杂度。
  • 空间复杂度:(O(1)),使用了常数空间来存储矩阵和中间结果。

方法四:斐波那契公式

解题步骤

完整的规范代码
import math
def climbStairs(n):
    """
    使用斐波那契公式解决爬楼梯问题
    :param n: int, 楼梯总步数
    :return: int, 爬到楼顶的方法数
    """
    sqrt5 = math.sqrt(5)
    fib_n = (((1 + sqrt5) / 2) ** (n + 1) - ((1 - sqrt5) / 2) ** (n + 1)) / sqrt5
    return int(fib_n)
# 示例调用
print(climbStairs(2))  # 输出: 2
print(climbStairs(3))  # 输出: 3
算法分析
  • 时间复杂度:(O(1)),直接计算。
  • 空间复杂度:(O(1)),不需要额外的存储空间。

方法五:递归加记忆化

解题步骤
  1. 递归定义:定义递归函数来计算 f(n)
  2. 记忆化:使用哈希表存储已计算的结果,避免重复计算。
  3. 递归计算:通过递归调用计算爬楼梯的方法数,并存储结果。
完整的规范代码
def climbStairs(n):
    """
    使用递归加记忆化解决爬楼梯问题
    :param n: int, 楼梯总步数
    :return: int, 爬到楼顶的方法数
    """
    memo = {1: 1, 2: 2}
    def recursive(n):
        if n not in memo:
            memo[n] = recursive(n - 1) + recursive(n - 2)
        return memo[n]
    return recursive(n)
# 示例调用
print(climbStairs(2))  # 输出: 2
print(climbStairs(3))  # 输出: 3
算法分析
  • 时间复杂度:(O(n)),递归中每个数值只计算一次。
  • 空间复杂度:(O(n)),存储递归过程中的中间结果和递归栈。

不同算法的优劣势对比

特征 方法一:动态规划 方法二:空间优化动态规划 方法三:矩阵快速幂 方法四:斐波那契公式 方法五:递归加记忆化
时间复杂度 (O(n)) (O(n)) (O(log n)) (O(1)) (O(n))
空间复杂度 (O(n)) (O(1)) (O(1)) (O(1)) (O(n))
优势 易于理解和实现 更节省空间 较快的计算时间 最快的计算效率 避免了冗余计算
劣势 较高的空间占用 没有明显劣势 实现复杂 精度问题可能影响结果 递归深度大时可能溢出

应用示例

计算理论研究:这些方法在计算理论和算法研究中非常有用,特别是在学习如何处理递归问题和优化问题解决方案的过程中。例如,在学术课程或算法竞赛中,不同的解决方案可以帮助理解各种算法技术的应用和优化。

软件开发:在软件开发中,如游戏程序或者路径规划算法中,这些方法可以用来解决实际问题,如寻找最优路径或者计算到达某个目标的不同方式,提高程序的效率和响应速度。


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

相关文章
|
3月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
118 2
|
1月前
|
程序员 C语言
【C语言】LeetCode(力扣)上经典题目
【C语言】LeetCode(力扣)上经典题目
|
1月前
|
Java C++ Python
【面试宝典】深入Python高级:直戳痛点的题目演示(下)
【面试宝典】深入Python高级:直戳痛点的题目演示(下)
|
1月前
|
设计模式 Unix Python
【面试宝典】深入Python高级:直戳痛点的题目演示(上)
【面试宝典】深入Python高级:直戳痛点的题目演示(上)
|
2月前
|
SQL Oracle 关系型数据库
CASE WHEN 语句的语法及示例,LeetCode 题目 “确认率” 练习
本文介绍了SQL中CASE语句的两种形式和语法,并通过LeetCode题目“确认率”的SQL查询示例展示了CASE语句在实际问题中的应用,解释了如何使用CASE语句计算特定条件的比率。
|
3月前
|
算法
LeetCode第12题目整数转罗马数字
该文章介绍了 LeetCode 第 12 题整数转罗马数字的解法,通过使用 TreeMap 按照整数从大到小排序,先使用大的罗马数字表示整数,再用小的,核心是先表示完大的罗马数字,想通此点该题较简单。
LeetCode第12题目整数转罗马数字
|
3月前
|
算法 Java
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
52 6
|
3月前
|
算法 Python
【Leetcode刷题Python】 LeetCode 2038. 如果相邻两个颜色均相同则删除当前颜色
本文介绍了LeetCode 2038题的解法,题目要求在一个由'A'和'B'组成的字符串中,按照特定规则轮流删除颜色片段,判断Alice是否能够获胜,并提供了Python的实现代码。
51 3
|
3月前
|
Python
【Leetcode刷题Python】50. Pow(x, n)
本文介绍了LeetCode第50题"Pow(x, n)"的解法,题目要求实现计算x的n次幂的函数,文章提供了递归分治法的详细解析和Python实现代码。
28 1
下一篇
无影云桌面