# 70.Climbing-Stairs

## 70. Climbing Stairs

## 题目地址

[https://leetcode.com/problems/climbing-stairs/](https://leetcode.com/problems/climbing-stairs/)

[https://www.jiuzhang.com/solutions/climbing-stairs](https://www.jiuzhang.com/solutions/climbing-stairs)

## 题目描述

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

## 代码

### Approach #1 Brute Force

```java
class Solution {
  public int climbStairs(int n) {
    return helper(0, n);
  }

  public int helper(int i, int n) {
    if (i > n)        return 0;
    if (i == n)        return 1;

    return helper(i + 1, n) + helper(i + 2, n);
  }

}
```

### Approach #2 Recursion with Memoization

```java
class Solution {
  public int climbStairs(int n) {
    int memo[] = new int[n + 1];
    return helper(0, n, memo);
  }

  private int helper(int i, int n, int memo[]) {
    if (i > n)    return 0;
    if (i == n)    return 1;
    if (memo[i] > 0)    return memo[i];

    memo[i] = helper(i + 1, n, memo) + helper(i + 2, n, memo);
    return memo[i];
  }

}
```

### Approach #3 Fibonacci Number

```java
class Solution {
  public int climbStairs(int n) {
    if (n == 1) {
        return 1;
    }
    int first = 1;
    int second = 2;
    for (int i = 3; i <= n; i++) {
        int third = first + second;
        first = second;
        second = third;
    }
    return second;
  }
}
```

### Approach #4 Dyanmic Programming

One can reach `i-th` step in one of the two ways:

1. Taking a single step from `i-1` step.
2. Taking a step of 2 from `i-2` step.

```java
public class Solution {
  public int climbStairs(int n) {
    if (n == 1)  return 1;

    int[] dp = new int[n + 1];
    dp[1] = 1;
    dp[2] = 2;
    for (int i = 3; i <= n; i++) {
        dp[i] = dp[i - 1] + dp[i - 2];
    }
    return dp[n];
  }
}
```

### Approach #5 Binets Method

**Complexity Analysis**

* Time complexity : &#x4F;_(lo&#x67;_&#x6E;). Traversing on logn bits.
* Space complexity : O(1). Constant space is used.

```java
 public class Solution {
    public int climbStairs(int n) {
        int[][] q = {{1, 1}, {1, 0}};
        int[][] res = pow(q, n);
        return res[0][0];
    }
    public int[][] pow(int[][] a, int n) {
        int[][] ret = {{1, 0}, {0, 1}};
        while (n > 0) {
            if ((n & 1) == 1) {
                ret = multiply(ret, a);
            }
            n >>= 1;
            a = multiply(a, a);
        }
        return ret;
    }
    public int[][] multiply(int[][] a, int[][] b) {
        int[][] c = new int[2][2];
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < 2; j++) {
                c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j];
            }
        }
        return c;
    }
}
```

### Approach #5 Fibonacci Formula

**Complexity Analysis**

* Time complexity : &#x4F;_(lo&#x67;_&#x6E;_). pow_ method takes nlo&#x67;_&#x6E;_ time.
* Space complexity : O(1). Constant space is used.

```java
public class Solution {
    public int climbStairs(int n) {
        double sqrt5 = Math.sqrt(5);
        double fibn=Math.pow((1+sqrt5)/2,n+1)-Math.pow((1-sqrt5)/2,n+1);
        return (int)(fibn/sqrt5);
    }
}
```
