leetcode: https://leetcode.com/problems/climbing-stairs/description/
一道经典的动态规划题。听了左程云大神的课之后,重新审视一边动态规划。
我们先假设不知道动态规划方法,我们这样思考:
f
(
n
)
=
f
(
n
−
1
)
+
f
(
n
−
2
)
f(n) = f(n-1)+f(n-2)
f(n)=f(n−1)+f(n−2)
然后就很自然的写出下面的递归解法
class Solution(object):
def climbStairs(self, n):
"""
:type n: int
:rtype: int
"""
if n == 1:
return 1
if n == 2:
return 2
sum = self.climbStairs(n-1) + self.climbStairs(n-2)
return sum
最后,毋庸置疑的超时。但是我们把尾递归改成循环,就通过了:
class Solution(object):
def climbStairs(self, n):
"""
:type n: int
:rtype: int
"""
if n == 1:
return 1
if n == 2:
return 2
a = 1
b = 2
i = 2
while(i < n):
b = a + b
a = b - a
i += 1
return b
接下来是记忆化搜索。之前的递归,存在太多的冗余计算。比如 f ( 5 ) = f ( 4 ) + f ( 3 ) f(5)=f(4)+f(3) f(5)=f(4)+f(3)和 f ( 4 ) = f ( 3 ) + f ( 2 ) f(4)=f(3)+f(2) f(4)=f(3)+f(2)都要算一遍 f ( 3 ) f(3) f(3)。我们通过把它记下来的方式,减少计算。
rec = dict()
class Solution(object):
def climbStairs(self, n):
"""
:type n: int
:rtype: int
"""
if n == 1:
rec[1] = 1
return 1
if n == 2:
rec[2] = 2
return 2
if n in rec:
return rec[n]
else:
sum = self.climbStairs(n-1) + self.climbStairs(n-2)
rec[n] = sum
return sum
这次递归也AC了。
记忆化搜索,还能怎么优化呢?就是按照简单到复杂依次计算,而不是无脑的记下来。这里巧了,就是对应之前的循环算法。