Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions climbing-stairs/flynn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## Description

다이나믹 프로그래밍을 이용하여 풀 수 있습니다.

아래와 같이 `memo` 배열을 정의했을 때,

```
memo[0] = 1
memo[1] = 1
memo[i] = distinct ways to climb to the i-th stair
```

다음과 같은 점화식이 성립합니다.

```
memo[i] = memo[i - 2] + memo[i - 1] (i > 1)
```

## Big-O

Time complexity: O(N)

Space complexity: O(N)

---

```cpp
class Solution {
public:
int climbStairs(int n) {
vector<int> memo(2, 1);

for (int i = 2; i <= n; i++) {
memo.push_back(memo[i - 1] + memo[i - 2]);
}

return memo[n];
}
};
```
47 changes: 47 additions & 0 deletions coin-change/flynn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
## Description

DP를 이용하여 풀이할 수 있습니다.

배열 `memo`를 아래와 같이 정의합니다.

```
memo[i] = i원을 만들기 위해 필요한 동전의 최소 개수
각 원소의 값은 초기값은 10^4 + 1로 설정함 (max(amount) / min(coin) + 1)
```

앞서 정의한 배열 `memo`를 이용하면 아래 점화식이 성립합니다.

```
memo[i] = min(memo[i], memo[i - coin] + 1) if i - coin >= 0
```

## Big-O

배열 `coins`의 크기를 `N`, 정수 `amount`의 크기를 `K`라고 했을 때,

Time complexity: `O(N * M)`

Space complexity: `O(M)`

---

```cpp
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
int MAX = 10000 + 1;
vector<int> memo(amount + 1, MAX);
memo[0] = 0;

for (int i = 1; i <= amount; i++) {
for (auto coin : coins) {
if (i - coin >= 0) {
memo[i] = min(memo[i], memo[i - coin] + 1);
}
}
}

return memo[amount] == MAX ? -1 : memo[amount];
}
};
```
73 changes: 73 additions & 0 deletions combination-sum/flynn.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 풀이 설명까지 감사합니다! ㅎㅎ 간결해서 보기 좋네요~!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니다

Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
## Description

`queue`를 이용한 BFS로 주어진 `candidates`의 조합을 만듭니다.

조합의 합 S의 크기에 따라 아래와 같이 연산을 진행합니다.

```
S < target: 조합에 새로운 수를 추가하여 queue에 다시 push
S == target: 정답 배열 res에 해당 조합을 push
S > target: 더 이상 queue에 조합을 등록하지 않음
```

## Big-O

`candidates` 배열의 크기를 `N`, `target`의 크기를 `T`, `candidates` 배열의 원소 중 가장 작은 원소의 크기를 `K`라고 했을 때,

Time complexity: `O(N ^ (T / K))`

- `queue`에 담긴 각 조합들은 최대 `N`개의 새로운 조합들을 만들어 낼 수 있습니다
- 이걸 `Tree`에 빗대어 생각해보면 각 `node` 당 `N`개의 자식들을 갖는다고 볼 수 있습니다
- `Tree`의 깊이는 `T / K`에 비례합니다

Space complexity: `O((T / K) * (N ^ (T / K)))`

- `queue`의 크기는 앞서 말한 `Tree`의 `node` 개수만큼 늘어날 수 있습니다
- `node`가 지닌 조합 배열의 크기는 `T / K` 까지 커질 수 있습니다

---

```cpp
class Solution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<int>> res;
queue<pair<int, pair<int, vector<int>>>> q; // {acc, {idx, combination}}

for (int i = 0; i < candidates.size(); i++) {
int num = candidates[i];

if (num <= target) {
vector<int> comb;
comb.push_back(num);
q.push({num, {i, comb}});
}

}

while (!q.empty()) {
auto p = q.front();
q.pop();

int acc = p.first, idx = p.second.first;
auto comb = p.second.second;

if (acc == target) {
res.push_back(comb);
} else if (acc < target) {
for (int i = idx; i < candidates.size(); i++) {
int num = candidates[i];

if (acc + num <= target) {
vector<int> new_comb(comb);
new_comb.push_back(num);
q.push({acc + num, {i, new_comb}});
}
}
}
}

return res;
}
};
```
39 changes: 39 additions & 0 deletions product-of-array-except-self/flynn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
## Description

한 칸씩 밀린 상태로 누적곱을 배열에 기록해주는 것을 두 번 진행해주면 원하는 바를 얻을 수 있습니다.

| index | 0 | 1 | 2 | 3 |
| ----- | --------- | --------- | --------- | --------- |
| value | 1 | 2 | 3 | 4 |
| acc-> | | 1 | 1 x 2 | 1 x 2 x 3 |
| <-acc | 2 x 3 x 4 | 3 x 4 | 4 | |
| res | 2 x 3 x 4 | 1 x 3 x 4 | 1 x 2 x 4 | 1 x 2 x 3 |

## Big-O

Time complexity: O(N)

Space complexity: O(N)

---

```cpp
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
vector<int> res(nums.size(), 1);

for (int i = 1; i < nums.size(); i++) {
res[i] *= nums[i - 1] * res[i - 1];
}

int acc = 1;
for (int i = nums.size() - 2; i >= 0; i--) {
acc *= nums[i + 1];
res[i] *= acc;
}

return res;
}
};
```
49 changes: 49 additions & 0 deletions two-sum/flynn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
## Description

`key: num, value: index`를 저장할 hashmap을 선언합니다.

배열 `nums`의 첫번째 원소를 hashmap에 저장합니다. (`nums[0]: 0`)

배열 `nums`를 두번째 원소부터 조회하여 `target - nums[i]`가 hashmap에 존재하는지 판단합니다.

만약 `target - nums[i]`가 hashmap에 존재한다면 정답 배열을 반환하고, 그렇지 않다면 hashmap에 새로운 쌍을 추가합니다.

## Big-O

주어진 배열 `nums`의 크기 N에 대해,

Time complexity: `O(N)`

- 배열 `nums`를 순회하기 때문에 `O(N)`의 시간 복잡도를 가집니다.

Space complexity: `O(N)`

- hashmap의 크기가 배열 `nums`의 크기에 가깝게 커질 수 있으므로 `O(N)`의 공간복잡도를 가집니다.

---

```cpp
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> past; // key: num value: index
vector<int> res;

past.insert({nums[0], 0});

for (int i = 1; i < nums.size(); i++) {
int remainder = target - nums[i];

if (past.find(remainder) != past.end()) {
res.push_back(i);
res.push_back(past[remainder]);
break;
} else {
past.insert({nums[i], i});
}
}

return res;
}
};
```