Skip to content

Commit 4c9df25

Browse files
authored
Merge branch 'DaleStudy:main' into main
2 parents 2267c00 + 774d101 commit 4c9df25

21 files changed

Lines changed: 714 additions & 0 deletions

File tree

coin-change/gcount85.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""
2+
# Intuition
3+
dp[n]은 n원을 만드는데 필요한 최소 동전 개수
4+
e.g. n = 11일 때, 11원을 만들기 위한 최소 동전 개수는 11에서 coins의 원소를 뺀 dp 값 + 1이다.
5+
6+
# Complexity
7+
- Time complexity: O(amount * coins.length)인데, coins 배열 길이가 상수라서 무시 => O(amount)
8+
9+
- Space complexity: dp 배열 생성으로 O(amount)
10+
"""
11+
12+
13+
class Solution:
14+
def coinChange(self, coins: list[int], amount: int) -> int:
15+
coins.sort()
16+
INF = float("inf")
17+
dp = [INF] * (amount + 1)
18+
dp[0] = 0
19+
for i in range(amount + 1):
20+
if dp[i] == INF:
21+
continue
22+
for c in coins:
23+
if i + c > amount:
24+
break
25+
dp[i + c] = min(dp[i + c], dp[i] + 1)
26+
return dp[-1] if dp[-1] != INF else -1

coin-change/hwi-middle.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
class Solution {
2+
public:
3+
int coinChange(vector<int>& coins, int amount) {
4+
if (amount < 1)
5+
{
6+
return 0;
7+
}
8+
9+
vector<int> v(amount);
10+
return solve(coins, amount, v);
11+
}
12+
13+
int solve(vector<int>& coins, int amount, vector<int>& count)
14+
{
15+
if (amount < 0) return -1;
16+
if (amount == 0) return 0;
17+
if (count[amount - 1] != 0) return count[amount - 1];
18+
19+
int min = INT_MAX;
20+
for (int coin : coins)
21+
{
22+
int res = solve(coins, amount - coin, count); // coin을 사용
23+
if (res >= 0 && res < min) // 결과가 유효하고 현재 최솟값보다 작으면 업데이트
24+
{
25+
min = res + 1; // coin을 미리 사용하고 찾은 값이므로 1 더함
26+
}
27+
}
28+
29+
count[amount - 1] = (min == INT_MAX) ? -1 : min;
30+
return count[amount - 1];
31+
}
32+
};

coin-change/liza0525.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# 7기 풀이
2+
# 시간 복잡도: O(n * k)
3+
# - 타겟 코인 값(amount, 복잡도 계산에선 n으로 표기)과 coins의 길이 만큼 탐색하며 계산
4+
# 공간 복잡도: O(n)
5+
# - 타겟 코인 값(amount, 복잡도 계산에선 n으로 표기) 만큼의 min_coin_count 계산 array를 생성
6+
class Solution:
7+
# 해당 문제는 현재 갖고 있는 돈으로 각 코인 값을 만드는 데에 동전을 얼마나 쓰는지 계산하여
8+
# 그 조합 중 가장 작은 값을 계속 찾아가는 문제로, min_coin_count를 사용한다.
9+
def coinChange(self, coins: List[int], amount: int) -> int:
10+
min_coin_count = [-1 for _ in range(amount + 1)] # 각 인덱스는 코인 값, value는 해당 코인 값을 만들 수 있는 동전의 개수(만들 수 없을 땐 -1)
11+
min_coin_count[0] = 0 # 코인 값이 0일 때는 동전을 쓰지 않으면 되므로 무조건 0이 된다.
12+
13+
for target_amount in range(1, len(min_coin_count)):
14+
# 각 코인 값에 대해 최소 동전 개수를 찾는다.
15+
for coin in coins:
16+
if target_amount - coin < 0:
17+
# 대상 코인 값보다 체크할 코인 값이 큰 경우에는 조합을 만들 수 없으므로 넘긴다
18+
continue
19+
if min_coin_count[target_amount - coin] < 0:
20+
# target_amount - coin(보수)을 만들 수 없으면 target_amount도 만들 수 없음
21+
# 예시) target=5, coin=3 → 보수 2를 못 만들면 5도 못 만듦
22+
continue
23+
24+
# 위 두 가지 조건만 넘어가면 동전 개수를 min_coin_count[target_amount]에 정해서 넣을 수 있다는 의미
25+
if min_coin_count[target_amount] == -1:
26+
# 값이 -1인 경우에는 처음으로 계산해서 넣는 것이기 때문에
27+
# min_coin_count[target_amount - coin]에다가 1을 더해서(coin 한 개를 추가 한다는 의미) min_coin_count[target_amount]에 할당
28+
min_coin_count[target_amount] = min_coin_count[target_amount - coin] + 1
29+
else:
30+
# 값이 -1이 아닌 경우는 이전에 저장된 동전 개수가 있으므로
31+
# 이전 결과 값과 min_coin_count[target_amount - coin] + 1의 값을 비교하여 더 적은 수를 저장한다.
32+
min_coin_count[target_amount] = min(
33+
min_coin_count[target_amount],
34+
min_coin_count[target_amount - coin] + 1
35+
)
36+
37+
# 모두 계산한 후 min_coin_count[amount]를 반환한다. (== amount를 만드는 동전의 최소 개수)
38+
return min_coin_count[amount]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""
2+
# Intuition
3+
이진탐색으로 찾는다.
4+
5+
# Complexity
6+
- Time complexity: nums의 길이 N일때, O(logN)
7+
8+
- Space complexity: 재귀스택 O(logN)
9+
"""
10+
11+
12+
class Solution:
13+
def findMin(self, nums: list[int]) -> int:
14+
l, m, r = 0, len(nums) // 2, len(nums) - 1
15+
16+
def findMinimum(l, m, r):
17+
if l == m or r == m:
18+
return min(nums[l], nums[r])
19+
20+
# 오른쪽 구간
21+
if nums[m] > nums[r]:
22+
return findMinimum(m, (m + r) // 2, r)
23+
24+
# 왼쪽 구간
25+
return findMinimum(l, (l + m) // 2, m)
26+
27+
return findMinimum(l, m, r)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
class Solution {
2+
public:
3+
int findMin(vector<int>& nums) {
4+
return solve(nums, 0, nums.size() - 1);
5+
}
6+
7+
int solve(vector<int>& num, int start, int end)
8+
{
9+
if (end - start < 2)
10+
{
11+
return min(num[start], num[end]);
12+
}
13+
14+
// 중간 인덱스 계산
15+
int mid = (start + end) / 2;
16+
17+
// 오름차순 정렬이 깨지기 시작한 부분 -> 최솟값 발견
18+
if (num[mid] < num[mid - 1])
19+
{
20+
return num[mid];
21+
}
22+
23+
// 왼쪽 영역이 정렬되어 있는 경우
24+
if (num[start] <= num[mid])
25+
{
26+
// 그리고 오른쪽 영역까지도 정렬된 경우
27+
if (num[mid] <= num[end])
28+
{
29+
// 가장 왼쪽에 있는 값이 최솟값
30+
return num[start];
31+
}
32+
33+
// 왼쪽 영역만 정렬된 경우
34+
// 오른쪽 영역에서 정렬이 깨지는 부분 찾으러 가기
35+
return solve(num, mid + 1, end);
36+
}
37+
38+
// 오른쪽 영역이 정렬된 경우
39+
// 왼쪽 영역에서 정렬이 깨지는 부분 찾으러 가기
40+
return solve(num, start, mid - 1);
41+
}
42+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// TC: O(log n)
2+
// SC: O(1)
3+
func findMin(nums []int) int {
4+
min := nums[0]
5+
l, r := 0, len(nums)-1
6+
7+
for l <= r {
8+
if nums[l] < min {
9+
min = nums[l]
10+
}
11+
break
12+
}
13+
14+
m := l + (r-l)/2
15+
if nums[m] < min {
16+
min = nums[m]
17+
}
18+
19+
if nums[m] >= nums[l] {
20+
l = m + 1
21+
} else {
22+
r = m - 1
23+
}
24+
}
25+
return min
26+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// TC: O(n)
2+
// SC: O(n)
3+
use std::cell::RefCell;
4+
use std::rc::Rc;
5+
6+
impl Solution {
7+
pub fn max_depth(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
8+
match root {
9+
None => 0,
10+
Some(node) => {
11+
let node = node.borrow();
12+
1 + std::cmp::max(
13+
Self::max_depth(node.left.clone()),
14+
Self::max_depth(node.right.clone()),
15+
)
16+
}
17+
}
18+
}
19+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""
2+
# Intuition
3+
1) BFS + 큐
4+
2) DFS + 재귀
5+
1번으로 풀었다가 2번이 코드가 더 간결해서 바꿨습니다.
6+
7+
# Complexity
8+
- Time complexity: 모든 노드를 다 봐야 하므로 O(N)
9+
10+
- Space complexity: 재귀 깊이만큼 O(H)
11+
"""
12+
13+
14+
class Solution:
15+
def maxDepth(self, root: Optional[TreeNode]) -> int:
16+
if not root:
17+
return 0
18+
return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class TreeNode {
2+
val: number;
3+
left: TreeNode | null;
4+
right: TreeNode | null;
5+
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
6+
this.val = val === undefined ? 0 : val;
7+
this.left = left === undefined ? null : left;
8+
this.right = right === undefined ? null : right;
9+
}
10+
}
11+
12+
/**
13+
* Time Complexity: O(n)
14+
* Space Complexity: O(h)
15+
*/
16+
function maxDepth(root: TreeNode | null): number {
17+
if (root === null) return 0;
18+
19+
let left = maxDepth(root.left);
20+
let right = maxDepth(root.right);
21+
22+
return 1 + Math.max(left, right);
23+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Definition for a binary tree node.
3+
* struct TreeNode {
4+
* int val;
5+
* TreeNode *left;
6+
* TreeNode *right;
7+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
8+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
9+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
10+
* };
11+
*/
12+
class Solution {
13+
public:
14+
int maxDepth(TreeNode* root) {
15+
return solve(root, 0);
16+
}
17+
18+
int solve(TreeNode* root, int depth)
19+
{
20+
if (root == nullptr)
21+
{
22+
return depth;
23+
}
24+
25+
int l = solve(root->left, depth);
26+
int r = solve(root->right, depth);
27+
28+
return max(l, r) + 1;
29+
}
30+
};

0 commit comments

Comments
 (0)