# 70. Climbing Stairs

**<font color=red>难度: Easy</font>**

## 刷题内容

> 原题连接

* 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.

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
```

## 解题方案

> 思路 1
******- 时间复杂度: O(N)******- 空间复杂度: O(N)******

[Fibonacci 的DP版本](https://github.com/apachecn/awesome-algorithm/blob/master/docs/Leetcode_Solutions/Python/Summary/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E7%9A%84DP%E6%80%9D%E8%80%83.md)

Top down， 记忆化搜索, beats 96.64%

这里cache用dict，用array也一样。

```python
class Solution(object):
    cache = {
        1: 1,
        2: 2
    }
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n in self.cache:
            return self.cache[n]
        self.cache[n] = self.climbStairs(n-1) + self.climbStairs(n-2)
        return self.cache[n]
```





> 思路 2
******- 时间复杂度: O(N)******- 空间复杂度: O(N)******


采用bottom up思想, 动态规划，beats 96.64%

```python
class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        cache = [1] * (n+1)
        for i in range(2, n+1):
            cache[i] = cache[i-1] + cache[i-2]
        return cache[-1]
```



> 思路 3
******- 时间复杂度: O(N)******- 空间复杂度: O(1)******

当然用bottom up还有一点，可以只存每次最后两个数，可以save space.，这样就只用到constant space.

永远只存3个元素，save space, beats 96.64%

```python
class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        cache = [1, 2, 3]
        if n < 4:
            return cache[n-1]
        for i in range(3, n+1):
            cache[2] = cache[0] + cache[1]
            cache[0], cache[1] = cache[1], cache[2]
        return cache[2]
```
        
> 思路 4
******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)******

另外还有一个公式法：

![](https://github.com/Lisanaaa/myTODOs/blob/master/41512784914_.pic.jpg)

由于这里面相当于```standard Fibonacci```函数向前进了一步，排列为1，2，3，5而非原本的1，1，2，3，所以代码中使用```n+1```

时间复杂度为O(lgN)是因为pow(X, Y)函数的时间复杂度:
- 当 Y < 2^63, lgY
- 当 Y >= 2^63, e^(Y * lgX)

```python
class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        sqrt5 = math.sqrt(5)
        fibn = pow((1 + sqrt5) / 2, n+1) - pow((1 - sqrt5) / 2, n+1)
        return int(fibn/sqrt5)
```

