## 70. Climbing Stairs
###### tags: `Dynamic Programming` `Easy`
>[70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/description/)
<br>
:::info
:::spoiler *Optimal Space & Time Complexity*
<br>
```
- Time complexity: O()
- Space complexity: O()
```
:::
<br>
## Thoughts & Solutions
### YC
:::spoiler Code
```javascript=
// Time: O(n), Space: O(n)
var climbStairs = function(n) {
if(n===1 || n===2) return n;
//iteration
const stairs=new Array(n);
stairs[0] = 1;
stairs[1] = 2;
for(let i=2;i<n;i++){
stairs[i] = stairs[i-1]+stairs[i-2];
}
return stairs[n-1];
};
```
:::
<hr/>
### Sol
:::spoiler Code
```javascript=
function helper(n, memo){
if(n === 1 || n === 0) return 1;
if(!(n in memo)) {
memo[n] = helper(n-1, memo) + helper(n-2, memo)
}
return memo[n];
}
/**
* @param {number} n
* @return {number}
*/
var climbStairs = function(n) {
const memo = {}
return helper(n, memo)
};
```
:::
<hr/>
### 東
1. Recursion with Time O(2^n) =>
2. Recursion with Memoization =>
3. Dynamic Programming with Array storing sequential result =>
4. Dynamic Programming Concept without array
Howard:
Solution 2 is also Dynamic Programming (top-down): **Memoization**
Solution 3, 4 is Dynamic progrmming (bottom-up): **Tabulation**
:::spoiler Code
```javascript=
// [Solution 1] Recursion
// Time O(2^n) | Space O(n)
var climbStairs = function(n) {
if(n === 1) return 1;
if(n === 2) return 2;
return climbStairs(n-1) + climbStairs(n-2);
};
// [Solution 2] Recursion with Memoization
// Time O(n) | Space O(n)
var climbStairs = function(n, memoizeMap = {1 : 1, 2 : 2}) {
if(memoizeMap.hasOwnProperty(n)) return memoizeMap[n];
memoizeMap[n] = climbStairs(n-1, memoizeMap) + climbStairs(n-2, memoizeMap);
return memoizeMap[n];
};
// [Solution 3] Dynamic Programming
// Time O(n) | Space O(n) (without call stack)
var climbStairs = function(n) {
const dp = new Array(n).fill(0);
dp[0] = 1;
dp[1] = 2;
for (let i = 2; i < n; i++) {
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n-1];
};
// [Solution 4] Revised from Solution 3 without using array
// Time O(n) | Space O(1)
var climbStairs = function(n) {
let prev = 1;
let curr = 1;
for (let i = 2; i <= n; i++) {
[prev, curr] = [curr, prev + curr];
}
return curr;
};
```
:::
<hr/>
### Jessie
:::spoiler Code
```javascript=
```
:::
<hr/>
### Howard
:::spoiler Code
```python=
class Solution:
def climbStairs(self, n: int) -> int:
# subproblem: 到第n階的走法,是到第n-1的走法+到第n-2的走法
# dp top down (memoization)
# time O(n)
# space O(n)
self.memo = {}
return self._climbStairs(n)
def _climbStairs(self, n):
if n == 1:
return 1
if n == 2:
return 2
if n in self.memo:
return self.memo[n]
self.memo[n-1] = self._climbStairs(n-1)
self.memo[n-2] = self._climbStairs(n-2)
return self.memo[n-1] + self.memo[n-2]
```
:::
<hr/>
### Haoyu
* [用Javascript實現階層與排列組合吧!](https://eruditeness.news.blog/2019/08/11/%E7%94%A8javascript%E5%AF%A6%E7%8F%BE%E9%9A%8E%E5%B1%A4%E8%88%87%E6%8E%92%E5%88%97%E7%B5%84%E5%90%88%E5%90%A7/)
```
// [1]
// 1
// c10
// [2]
// 1, 1
// 2
// c20 + c11
// [3]
// 1, 1, 1
// 2, 1
// 1, 2
// c30 + c21
// [4]
// 1, 1, 1, 1
// 2, 1, 1
// 1, 2, 1
// 1, 1, 2
// 2, 2
// [4/2, ..., 4]
// c40 + c31 + c22
// [5]
// 1, 1, 1, 1, 1
// 1, 2, 1, 1
// 1, 1, 2, 1
// 1, 1, 1, 2
// 2, 2, 1
// [5/2, ... ,5]
// c50 + c41 + c32
```
:::spoiler Code
```javascript=
/**
* @param {number} n
* @return {number}
*/
var climbStairs = function(n) {
function fraction(n) {
let result = 1;
while (n > 0) {
result *= n;
n -= 1;
}
return result;
}
function permutation (c, n){
return fraction(c) / (fraction(n) * fraction(c - n));
}
const maxTwoStep = (n - n % 2) / 2;
let sum = 0;
for (let i = 0; i <= maxTwoStep; i += 1) {
const [countTotal, countTwoStep] = [n - i, i];
sum = sum += permutation(countTotal, countTwoStep);
}
return sum;
};
```
:::
<hr/>
<br>
## Live Coding
:::spoiler (name)
```
// write your code here
```
:::