爬楼梯问题

爬楼梯的问题通常出现在一些面试场景种。爬楼梯问题是一个常见的计算机科学问题,通常用于学习和理解关键编程概念,如动态规划、递归和记忆。

首先,让我们更好地理解问题本身。

问题定义

给定一个楼梯,假设它有 n 个台阶。您可以选择每次爬一个、两个或三个台阶。问题是,有多少种可能的方法可以爬到楼梯的顶部?

这个问题在数学中被称为斐波那契变体,因为它的解涉及类似的递归结构。

使用 Python 爬楼梯

在爬楼梯问题中,我们需要计算所有可能的组合才能到达楼梯的顶部。由于它有限制,我们一次只能爬一个或两个台阶,所以我们可以选择踩踏或跳过一个台阶。

【面试常见】Python 解决爬楼梯问题_斐波那契数列

输入:n = 1
输出:1 爬 1 个楼梯只有一种方法
输入:n=2
输出:2 有两种方式:(1、1) 和 (2)
输入:n = 4
输出:5 (1, 1, 1, 1), (1, 1, 2), (2, 1, 1), (1, 2, 1), (2, 2)

有很多方法可以解决这个问题。最简单的方法之一是使用斐波那契数列方法。

因此,以下是如何使用 Python 编程语言解决爬楼梯问题:

def climbStairs(num):
    a = 1
    b = 1
    n = num - 1
    for i in range(n):
        c = a
        a = a + b
        b = c
    return a

print(climbStairs(4))

输出

5

递归

最直接的方法是使用递归。基本思想是,每次爬楼梯时,你有三个选项,然后递归求解剩余的步数。

def climbStairs(n):
    if n <= 0:
        return 0
    elif n == 1:
        return 1
    elif n == 2:
        return 2
    elif n == 3:
        return 4
    else:
        return climbStairs(n-1) + climbStairs(n-2) + climbStairs(n-3)

说明:因为每次爬楼梯有三种选择,对于n级台阶,可以选择先上第一步,可以选择先上第二级台阶,也可以选择先上第三级台阶

那么解决n级台阶的方法数就变成了: 求解爬 (n-1) 楼梯的方式数 + 爬 (n-2) 楼梯的方式数 + 爬 (n-3) 楼梯的方式数。

上述代码的缺点是,由于重复计算很多,运行时间会随着 n 的增加呈指数级增加。

记忆递归

为了避免重复计算,可以使用一种叫做“记忆”的技术,即保存计算结果,当需要再次计算时,直接将结果从存储空间中取出。

def climbStairs(n, memo={<!-- -->}):
    if n <= 0:
        return 0
    elif n == 1:
        return 1
    elif n == 2:
        return 2
    elif n == 3:
        return 4
    elif n not in memo:
        memo[n] = climbStairs(n-1) + climbStairs(n-2) + climbStairs(n-3)
    return memo[n]

此代码将以前计算的值存储在名为“memo”的字典中。

如果要计算的值已经在“memo”中,则直接返回该值,否则执行计算并将结果存储在“memo”中。

需要注意的是,虽然这里是作为默认参数初始化为空字典的,但由于Python默认参数的特性,即在定义函数时只会初始化一次,所以在多次调用函数时,这个字典实际上是共享的。

完整代码

def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)
 
def countWays(s):
    return fib(s + 1)
  

s = 4
print "结果 = ",
print countWays(s)