题目描述:假设你正在爬楼梯,需要n步你才能到达顶部。但每次你只能爬一步或者两步,你能有多少种不同的方法爬到楼顶部?
样例:比如n=3,1+1+1=1+2=2+1=3,共有3中不同的方法,返回 3
从这道题目开始,我们来解决一类之前从未接触过的算法问题:动态规划。
动态规划与之前接触的“分治法”(详见:点击打开链接)类似,都是将一个大问题分解为小问题解决,最后将小问题的解按照某种规则合并,得到大问题的解。但是与“分治法”不同的是,分治法解决的小问题和小问题之间是互不影响的,而这样就会导致一些子问题之间有公共子问题的问题被重复解决,造成不必要的浪费。所以,我们设想,能否用一个类似于表格的东西将每一步小问题的解记录下来,以时间换取空间,最后用递归算法将这些子问题的解整合(当然,用的递归算法也不是典型的递归,典型的递归是“从大到小”,而动态规划则是“从小到大”,更严格的说,是借助了递归的思路)。所以,我们将这种用表格法记录子问题的解,再递归整合的算法称之为“动态规划”,英文说叫做“dynamic programing”,这里的“programing”是表格的意思,而并非“编程”的意思。现实中,我们常用这种算法来解决最优化问题。所以,由动态规划的由来我们也就能发现,它会和递归,贪心这些算法有着天然的密切联系。
看这个题目吧,n级台阶,每次能上一步或两步,问有多少走法。动态规划问题的核心就在于找到大问题与小问题之间的关系。这个题目是什么关系呢?可以想,走到第i级台阶有几种方法呢,2种。
1. 从i - 1级走一步到n级
2. 从i - 2级走两步到n级
那也就是说,走到第i级台阶的走法有f[i] = f[i - 1] + f[i - 2],也就是用第i - 1级台阶的走法加上第i - 2级台阶的走法。
于是,可以这样设计:用一个数组,record,record[i]保存有i级台阶时有多少走法,类似与递归,数组每一项的的结果由前两项加和得到,触底的条件是i = 0, i = 1时,结果都是1.
代码如下:
class Solution:
"""
@param n: An integer
@return: An integer
"""
def climbStairs(self, n):
record = [1, 1]
if n >= 2:
for i in range(2, n + 1):
record.append(record[i - 1] + record[i - 2])
return record[n]
# write your code here
record[i]保存的是当有i级台阶时,一共多少种走法。