|
| 1 | +class Solution: |
| 2 | + def climbStairsFact(self, n: int) -> int: |
| 3 | + """ |
| 4 | + Intuition: |
| 5 | + 1 + 1 + ... + 1 는 2가 0개일 때 n을 만들 수 있는 경우의 수 = 1. |
| 6 | + 1 + 2 + ... + 1 는 2가 1개일 때 n을 만들 수 있는 경우의 수 = (n-1)C1. |
| 7 | + 2 + 2 + ... + 1 는 2가 2개일 때 n을 만들 수 있는 경우의 수 = (n-2)C2. |
| 8 | + ... |
| 9 | + 즉, n이 0부터 최대로 놓을 수 있는 값(two_cnt)까지 |
| 10 | + 1로 놓여져 있는 배열에서 2의 위치를 선택(조합)하는 것과 같다. |
| 11 | +
|
| 12 | + Time Complexity: |
| 13 | + O(N^2 log N): |
| 14 | + (n-i)Ci는 O((N - i) log i)이고, i가 0부터 two_cnt까지 증가할 경우 |
| 15 | + 대략 O(N log N)로 계산한다. |
| 16 | + 이를 two_cnt(N//2) 까지 반복하므로, O(N^2 log N). |
| 17 | +
|
| 18 | + Space Complexity: |
| 19 | + O(1): |
| 20 | + answer를 업데이트 해가며 값 계산. |
| 21 | + """ |
| 22 | + import math |
| 23 | + |
| 24 | + two_cnt = n // 2 |
| 25 | + answer = 1 |
| 26 | + |
| 27 | + for i in range(1, two_cnt + 1): |
| 28 | + # (n - i)Ci |
| 29 | + # 여기서 int로 형변환 할 경우 수치적 불안정 발생 |
| 30 | + answer += math.factorial(n - i) / math.factorial(n - 2 * i) / math.factorial(i) |
| 31 | + |
| 32 | + return int(answer) # int로 형변환 하지 않을 경우 TypeError |
| 33 | + |
| 34 | + def climbStairsComb(self, n: int) -> int: |
| 35 | + """ |
| 36 | + Intuition: |
| 37 | + `climbStairsFact`에서 Factorial은 수치적 불안정성으로 인해 |
| 38 | + 더욱 안정적인 math.comb를 사용한다. |
| 39 | +
|
| 40 | + Time Complexity: |
| 41 | + O(N^2 log N): |
| 42 | + (n-i)Ci는 O((N - i) log i)이고, i가 0부터 two_cnt까지 증가할 경우 |
| 43 | + 대략 O(N log N)로 계산한다. |
| 44 | + 이를 two_cnt(N//2) 까지 반복하므로, O(N^2 log N). |
| 45 | +
|
| 46 | + Space Complexity: |
| 47 | + O(1): |
| 48 | + answer를 업데이트 해가며 값 계산. |
| 49 | + """ |
| 50 | + import math |
| 51 | + |
| 52 | + two_cnt = n // 2 |
| 53 | + answer = 1 |
| 54 | + |
| 55 | + for i in range(1, two_cnt + 1): |
| 56 | + # (n - i)Ci |
| 57 | + # math.comb 메소드는 수치적으로 안정적으로 계산해준다 |
| 58 | + answer += math.comb(n - i, i) |
| 59 | + return answer |
| 60 | + |
| 61 | + def climbStairsFib(self, n: int) -> int: |
| 62 | + """ |
| 63 | + Intuition: |
| 64 | + climb stairs 문제는 대표적인 피보나치 수열 문제이다. |
| 65 | + 실제로 경우의 수를 계산해보면, |
| 66 | + 1 -> 1 |
| 67 | + 2 -> 2 |
| 68 | + 3 -> 3 |
| 69 | + 4 -> 5 |
| 70 | + 5 -> 8 |
| 71 | + ... |
| 72 | + 로 피보나치 수열을 따르는 것을 알 수 있다. |
| 73 | +
|
| 74 | + Time Complexity: |
| 75 | + O(N): |
| 76 | + N번 순회하여 피보나치 수열 구현. |
| 77 | +
|
| 78 | + Space Complexity: |
| 79 | + O(N): |
| 80 | + N개 만큼 해시 key-value 쌍을 저장. |
| 81 | + """ |
| 82 | + fib_dict = {1: 1, 2: 2, 3: 3} |
| 83 | + for i in range(1, n + 1): |
| 84 | + if i not in fib_dict: |
| 85 | + fib_dict[i] = fib_dict[i - 1] + fib_dict[i - 2] |
| 86 | + if i == n: |
| 87 | + return fib_dict[i] |
0 commit comments