LeetCode-70 climbing stairs(方法大总结)

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]
"""

你可能感兴趣的:(python)