https://leetcode.com/problems/climbing-stairs/description/
题目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.
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.
Example 1:
Input: 2 Output: 2 Explanation: There are two ways to climb to the top. 1. 1 step + 1 step 2. 2 steps
Example 2:
Input: 3 Output: 3 Explanation: There are three ways to climb to the top. 1. 1 step + 1 step + 1 step 2. 1 step + 2 steps 3. 2 steps + 1 step
#_*_coding:utf-8_*_ """ 不知道是不是史上最全的python版本的fibonacci,希望如此了 1、递归(时间复杂度较高,LeetCode会因为超时无法通过) 2、动态规划法 3、利用列表和函数的方法 4、节省空间 5、Binets Method(矩阵的方法) 6、fibonacci公式的方法 7、ACM版本 8、总结一下参照的网上各路大神的方法,网址如下 https://leetcode.com/problems/climbing-stairs/solution/ https://www.cnblogs.com/figure9/archive/2010/08/30/1812927.html https://www.cnblogs.com/nklzj/p/6103117.html https://blog.csdn.net/u014496330/article/details/44650911 https://blog.csdn.net/minxihou/article/details/51694824 """
#_*_coding:utf-8_*_
"""
不知道是不是史上最全的python版本的fibonacci,希望如此了
1、递归(时间复杂度较高,LeetCode会因为超时无法通过)
2、动态规划法
3、利用列表和函数的方法
4、节省空间
5、Binets Method(矩阵的方法)
6、fibonacci公式的方法
7、ACM版本
8、总结一下参照的网上各路大神的方法,网址如下
https://leetcode.com/problems/climbing-stairs/solution/
https://www.cnblogs.com/figure9/archive/2010/08/30/1812927.html
https://www.cnblogs.com/nklzj/p/6103117.html
https://blog.csdn.net/u014496330/article/details/44650911
https://blog.csdn.net/minxihou/article/details/51694824
"""
"""
step 1:递归的方法
class Solution:
def climbStairs(self, n):
if n == 1:
return 1
if n == 2:
return 2
else:
return self.climbStairs(n - 1) + self.climbStairs(n - 2)
"""
"""
step 2:动态规划法(32ms)
class Solution:
def climbStairs(self, n):
if n == 1:
return 1
if n == 2:
return 2
a , b = 1, 1
for i in range(n):
a , b = b , a+b
return a
"""
"""
step 3:利用列表和函数的方法(72ms)
class Solution:
def climbStairs(self, n):
result = [1, 2]
for i in range(n - 2):
result.append(result[-2] + result[-1])
return result[n-1]
"""
"""
step 4:节省空间72 ms
class Solution:
def climbStairs(self, n):
arr = [1,2,3] # 计算数组中任意一项,需要用到的变量不超过3个,因此只需要用一个长度为3的数组
for i in range(n):
arr.append(arr[i % 3]) # 第n祥依次放在下标为n%3的数组中
# 将该数组看成一个循环链表,则每一项输出后,相应的位置用来放项数比它大3的值,而这个值就是数组的后两项相加
arr[i % 3] = arr[(i + 1) % 3] + arr[(i + 2) % 3]
#此时,arr中应该是[377, 144, 233, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]从第三项开始是n的fibonacci数列,
# 前面的三项是经过arr[i % 3] = arr[(i + 1) % 3] + arr[(i + 2) % 3]得到的值,可以用print(arr[3:])看到arr
return arr[-1]
"""
"""
step 5:矩阵法,公式:
f[n] 1 1 f[n-1]
= *
f[n-1] 1 0 f[n-2]
代码中m1构造的是一个矩阵的乘法,m2构造的是一个转置矩阵。
我们用reduce这个方法加上[[[0,1],[1,1]] for i in range(n-1)来对[[0,1],[1,1]]这个矩阵做一个降阶操作。
简单说一下reduce方法:
reduce内建函数,一个二元操作函数,用传给reduce先对集合中的第1,2个数据进行操作,得到的结果再与第三个数运算最后得到一个结果。
在这句话最后为什么会有个[0],因为我们要拿到的当然是fib(n)这个数啦。
以为整个操作运算量体现在对[[0,1],[1,1]]的降阶上所以该算法的时间复杂度是线性的O(n)。
"""
from functools import reduce
class Solution:
def climbStairs(self,n):
def m1(a,b):
m = [[],[]]
m[0].append(a[0][0]*b[0][0]+a[0][1]*b[1][0])
m[0].append(a[0][0]*b[0][1]+a[0][1]*b[1][1])
m[1].append(a[1][0]*b[0][0]+a[1][1]*b[1][0])
m[1].append(a[1][0]*b[1][0]+a[1][1]*b[1][1])
print(m)
return m
def m2(a,b):
m=[]
m.append(a[0][0]*b[0][0]+a[0][1]*b[1][0])
m.append(a[1][0]*b[0][0]+a[1][1]*b[1][0])
return m
return m2(reduce(m1,[[[0,1],[1,1]] for i in range(n-1)]),[[1],[2]])[0]
"""
step 6:fibonacci公式的方法(针对初始为0,1的情况)
Fib(n) = [(1+√5)/2]^n /√5 - [(1-√5)/2]^n /√5
import math
class Solution:
def climbStairs(self,n):
return round((pow((1 + math.sqrt(5)) / 2,n+1 ) + pow((1 - math.sqrt(5)) / 2, n+1 )) / math.sqrt(5))
s = Solution()
print(s.climbStairs(10))
"""
"""
step 7:ACM版本
看过上一个fib函数就比较容易理解这一个版本了,这个版本同样采用了二元变换的方式求fib(n)。不过区别在于这个版本的复杂度是lgn,而上一个版本则是线性的。
这个版本的不同之处在于,它定义了一个矩阵的快速求幂操作fib_iter,原理很简单,可以类比自然数的快速求幂方法,所以这里就不多说了。
class Solution:
def climbStairs(self,n):
lhm=[[0,1],[1,1]]
rhm=[[1],[1]]
em=[[1,0],[0,1]]
#multiply two matrixes
def matrix_mul(lhm,rhm):
#initialize an empty matrix filled with zero
result=[[0 for i in range(len(rhm[0]))] for j in range(len(rhm))]
#multiply loop
for i in range(len(lhm)):
for j in range(len(rhm[0])):
for k in range(len(rhm)):
result[i][j]+=lhm[i][k]*rhm[k][j]
return result
def matrix_square(mat):
return matrix_mul(mat,mat)
#quick transform
def fib_iter(mat,n):
if not n:
return em
elif(n%2):
return matrix_mul(mat,fib_iter(mat,n-1))
else:
return matrix_square(fib_iter(mat,n/2))
return matrix_mul(fib_iter(lhm,n),rhm)[0][0]
"""