【LeetCode】70. 爬楼梯

问题描述

You are climbing a stair case. It takes n steps to reach to the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

Note: Given n will be a positive integer.

你正在爬楼梯。需要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 步

Python 实现

其实这是一个很经典的算法题,乍看之下不知道从何下手,但我们可以换个角度来看:从结果出发

根据题目可知,每次行动只有两种可能,要么爬 1 级台阶,要么爬 2 级台阶,所以我们可以这么来思考:假设到达第 n 个台阶共有 f(n) 种方式,则

  • 到达第 n 个台阶,要么从 第 n-1 个台阶爬 1 级台阶到达,要么从 第 n-2 个台阶爬 2 级台阶到达。到达第 n-1 个台阶共有 f(n-1) 种方式,到达第 n-2 个台阶共有 f(n-2) 种方式,所以 f(n) = f(n-1) + f(n-2);
  • 到达第 n-1 个台阶,要么从 第 n-2 个台阶爬 1 级台阶到达,要么从 第 n-3 个台阶爬 2 级台阶到达。到达第 n-2 个台阶共有 f(n-2) 种方式,到达第 n-3 个台阶共有 f(n-3) 种方式,所以 f(n-1) = f(n-2) + f(n-3);
  • 。。。

显然,这个问题的答案就是一个斐波拉契数列了。斐波拉契数列的表达式:f(n) = f(n-1) + f(n-2)。

在该问题中,两个基础条件是 f(2) = 2,f(1) = 1。

因此,最后代码实现一个斐波拉契数列就可以了。

 

实现一:递归实现

这种实现方式很直观,但是有经验的朋友都知道,在这个过程中,有些结果被重复计算,浪费的计算资源。例如

  • f(n) = f(n-1) + f(n-2)
  • f(n-1) = f(n-2) + f(n-3)

在这里 f(n-2) 就被重复计算了两遍。不仅如此,当 n 的值特别大的时候,使用递归实现很可能因为函数调用次数过多,从而导致栈溢出。因此,实现斐波拉契数列常常使用下面第二种方法。

class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """

        if n == 1:
            return 1
        if n == 2:
            return 2
        
        # May be stack overloaded.
        return self.climbStairs(n-1) + self.climbStairs(n-2)

 

实现二:数组(列表)实现

斐波拉契数列实际上从 1 到 n 分别对应一个结果值,因此使用数组或者列表来记录结果最直观。

class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        
        if n == 1:
            return 1
        if n == 2:
            return 2

        F = [1, 2]
        for i in range(n-2):
            F.append(F[-1] + F[-2])
        return F[-1]

 

实现三:直接获取结果

同样是斐波拉契数列的一种实现形式,由于我们只需要获取值为 n 时的结果,因此通过分析得到基础条件的值(f(2) = 2, f(1) = 1)之后,我们可以直接通过斐波拉契数列的计算公式,算出最后 f(n) 的值返回即可,这样就可以避免使用数组或者列表记录中间值,以节省内存空间。

class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
     
        if n == 1:
            return 1
        if n == 2:
            return 2

        s = 0
        a = 2
        b = 1
        for i in range(n-2):
            s = a + b
            b = a
            a = s
            
        return s
        

 

链接:https://leetcode.com/problems/climbing-stairs/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值