学习参考视频:华为算法大佬耗时200小时录制:Leetcode刷题100道,足以吊打字节面试官!_哔哩哔哩_bilibiliicon-default.png?t=M1L8https://www.bilibili.com/video/BV1eg411w7gn?p=5

题目描述:

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

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

解题思路:

思路一:自上而下——递归

import time

def climbStairs(n):

    if n == 1:
        return 1
    elif n == 2:
        return 2
    else:
        return climbStairs(n-1)+climbStairs(n-2)
    # 解释:如果楼梯数目不是一层或两层,那么我们有多少种走法呢?
    # 这里我们仅仅考虑第一步:第一步有两种走法,一层或两层,则我们的总走法就是这两种情况下分别的走法之和

time1_1 = time.time()
print(climbStairs(30))
time1_2 = time.time()
print(time1_2-time1_1)

结果:时间复杂度过高 time = 0.19949626922607422

于是我们试图优化代码,由于递归的过程包含着大量的重复计算,如图:

可以看到,在求f(6)的过程中,f(3)被重复计算了3次,f(4)被重复计算了2次,那如果我们在第一次计算后,就将计算结果存储,就可以避免重复计算了。

在java里,这样的容器叫做Hashmap,在python里,可以用字典来实现。

dic = dict()
def climbStairs(n):
    if n == 1:
        return 1
    elif n == 2:
        return 2
    elif dic.get(n) is not None: # 说明之前已经计算过啦
        return dic.get(n)
    else:
        ret = climbStairs(n-1)+climbStairs(n-2) 
        dic[n] = ret # 计算后就要存储哦
        return ret

此时,运算时间已经为0.0.

千万不要先return ret再给dic赋值 ......

思路二:自下而上——循环

 这个图片很好的讲明白了循环的实现过程,本质上就是要把握赋值的顺序。

def climbStairs(n):
    if n == 1:
        return 1
    elif n == 2:
        return 2
    ret = 0
    pre = 2
    pre_pre = 1
    for i in range(3, n+1):
        ret = pre + pre_pre
        pre_pre = pre
        pre = ret
    return ret

 当然,运行时间也是0.

更多推荐