Leet Code 070-Climbing Stairs

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

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

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

示例 1:

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

输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1.  1 阶 + 1 阶 + 1 阶
2.  1 阶 + 2 阶
3.  2 阶 + 1 阶

fib数列 多种解法

思路一:暴力递归

  • 时间复杂度 O(2^n)
  • 空间复杂度,即递归树深度n,O(n)
def climbStairs(n):
    return n if n<=2 else climbStairs(n-1)+climbStairs(n-2)

思路二: 递归 + 记忆化

def climbStairs(n):
    cache = {1:1, 0:1}
    for i in range(2,n+1):
        cache[i] = cache[i-1] + cache[i-2]
    return cache[n]
climbStairs(10)
89

写一个做缓存的装饰器

def memo(fun):
    cache = {}
    def wrap(*args):
        if args[0] not in cache:
            cache[args[0]] = fun(*args)
        return cache[args[0]]
    return wrap
@memo
def climbStairs(n):
    return n if n<=2 else climbStairs(n-1)+climbStairs(n-2)
climbStairs(10)
89

思路三:动态规划

第 i 阶可以由以下两种方法得到:

在第 (i-1)阶后向上爬 1 阶。

在第 (i-2)阶后向上爬 2 阶。

到达第 i 阶的方法总数就是到第 (i-1) 阶和第 (i-2) 阶的方法数之和。

def climbStairs(n):
    dp = [0,1]
    for _ in range(n):
        dp[0],dp[1] = dp[1],dp[0]+dp[1]
    return dp[1]
climbStairs(10)
89
def climbStairs(n):
    a,b = 0,1
    for _ in range(n):
        a,b = b,a+b
    return b
climbStairs(10)
89

思路四:fib数列递推公式

  • 时间复杂度 O(logn),pow() takes logn
  • 空间复杂度O(1)
def climbStairs(n):
    import math
    sqrt5 = math.sqrt(5)
    fib = pow((1 + sqrt5) / 2, n+1) - pow((1 - sqrt5) / 2, n+1)
    return int(fib/sqrt5)
climbStairs(10)
89

思路五:fib数列的快速幂算法 使用矩阵和LeetCode050 pow(n, n)思想

image.png

  • 时间复杂度 O(logn) 因为可以采用快速幂算法(leetcode050 pow(x,n))
  • 空间复杂度 O(1)
def mul(a, b):  # 首先定义二阶矩阵乘法运算
    c = [[0, 0], [0, 0]]  # 定义一个空的二阶矩阵,存储结果
    for i in range(2):  # row
        for j in range(2):  # col
            for k in range(2):  # 新二阶矩阵的值计算
                c[i][j] += a[i][k] * b[k][j]
    return c

def fib(n):
    if n <= 1: return max(n, 0)
    res = [[1, 0], [0, 1]]  # 单位矩阵,等价于1
    A = [[1, 1], [1, 0]]  # A矩阵
    while n:
        if n & 1: res = mul(res, A)  # 如果n是奇数,或者直到n=1停止条件
        A = mul(A, A)  # 快速幂
        n >>= 1  # 整除2,向下取整
    return res[0][0]

fib(10)
89

爬楼梯变种,给出每次步长,eg: steps = [1, 2, 3] 求几种方法上 N 阶台阶

@memo
def climbBTStairs(n, steps):
    cnt = 0
    if n == 0:
        cnt = 1
    elif n > 0:
        for step in steps:
            cnt += climbBTStairs(n-step, steps)
    return cnt

climbBTStairs(10, [1,2,3])
274
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值