动态规划--爬楼梯
Posted 算法艺术
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划--爬楼梯相关的知识,希望对你有一定的参考价值。
爬楼梯是非常经典的面试问题,很多大公司都会将这个问题作为笔试的一部分,希望大家能深入理解,这个问题是LeetCode-70题,大家可以在LeetCode上找到更多相关问题,大家加油!
注意:给定 n 是一个正整数。
示例 1:输入:2 输出:2
解释:有两种方法可以爬到楼顶。1. 走1个台阶+ 走1个台阶 2. 走2个台阶
示例 2:输入:3 输出:3
解释:有三种方法可以爬到楼顶。1. 走1个台阶+ 走1个台阶+ 走1个台阶 2. 先走1个台阶 + 再走2个台阶 3. 先走2个台阶 + 再走1个台阶
因为每次可以走1个台阶或走2个台阶,要到达楼梯第n阶时,可以从第n-1阶向上再走1个到达n,也可以从第n-2阶再走2个台阶到达n
1
记忆化递归
算法:
class Solution:
meno = []
def climbStairs(self, n: int) -> int:
if n < 0:
return 0
self.meno = [-1 for i in range(n+1)]
return self.getStep(n)
def getStep(self,n:int) -> int:
# 状态转移方程 f(n) = f(n-1) + f(n-2)
# 自顶向下 递归
# 程序结束条件
if n == 0 or n == 1:
return 1
if self.meno[n] != -1:
return self.meno[n]
res = self.getStep(n-1) + self.getStep(n-2)
self.meno[n] = res
return res
时间复杂度:
空间复杂度:
2
动态规划
自低向上,可以被分解为一个最优子问题
动态转移方程:dp[n]=dp[n−1]+dp[n−2]
class Solution:
def climbStairs(self, n: int) -> int:
if n < 0:
return 0
# 自低向上 动态规划
memo = [-1 for i in range(n+1)]
memo[0] = 1
memo[1] = 1
for i in range(2,n+1):
memo[i] = memo[i-1] + memo[i-2]
return memo[n]
时间复杂度:
空间复杂度:
3
斐波那契数
上面我们用了n个空间来保存计算出来的结果,但是我们只需要爬到第n阶楼梯共多少种方法,只保存一个数字即可,因此我们只需开辟常数级的空间保存几个变量。
class Solution:
def climbStairs(self, n: int) -> int:
if n < 0:
return 0
# 自低向上 动态规划
first = 1
second = 1
thrid = -1
for i in range(2,n+1):
thrid = first + second
first = second
second = thrid
return second
时间复杂度:
空间复杂度:
4
斐波那契公式
我们可以根据数学归纳法,对状态转移方程进行推导,得出数学公式。
,所以f(n+1) = a^(n+1),f(n+2) = a^(n+2),转化f(n+1) = a * a^n,f(n+2) = a^2 * a^n。
由状态方程得:
a^2 * a^n = a * a^n + a^n
两边都除以a^n,并移项得:
a^2 - a - 1 = 0
解方程得:
a1 = 1/sqrt(5) * ((1+sqrt(5)) / 2)
a2 = 1/sqrt(5) * ((1-sqrt(5)) / 2)
所以一般形式为:
f(n) =
1/sqrt(5)*{ [ (1+sqrt(5)) / 2 ]^(n+1)- [ (1-sqrt(5)) / 2 ]^(n+1) }
class Solution:
def climbStairs(self, n: int) -> int:
if n < 0:
return 0
sqrt(5) =
pow((1+sqrt5)/2,n+1) - pow((1-sqrt5)/2,n+1) =
fibn / sqrt5 =
return res
时间复杂度:
空间复杂度:
一个问题的解决方法有很多,可以在时间和空间上进行优化,此问题还有更多解法,欢迎私信我,一起讨论,大家加油!
以上是关于动态规划--爬楼梯的主要内容,如果未能解决你的问题,请参考以下文章