Skip to content

Commit 467eb00

Browse files
authored
Merge branch 'DaleStudy:main' into main
2 parents 5f97cdc + dd62e82 commit 467eb00

File tree

144 files changed

+3763
-14
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

144 files changed

+3763
-14
lines changed

climbing-stairs/01-binary.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* @param {number} n
3+
* @return {number}
4+
*/
5+
6+
var climbStairs = function (n) {
7+
if (n === 1) return 1;
8+
if (n === 2) return 2;
9+
const arr = [0, 1, 2];
10+
let i = 3;
11+
while (i <= n) {
12+
const temp = arr[i - 1] + arr[i - 2];
13+
arr.push(temp);
14+
i++;
15+
}
16+
17+
return arr[n];
18+
};

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]

coin-change/sangbeenmoon.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# dp[i] = min(dp[i - c0], dp[i - c1], ... , dp[i - cn]) + 1
2+
3+
# TC : O(amount * len(coins))
4+
# SC : O(amount)
5+
6+
class Solution:
7+
dp = []
8+
def coinChange(self, coins: List[int], amount: int) -> int:
9+
self.dp = [-2] * (amount + 10) # 아직 방문하지 않음 -> -2
10+
11+
return self.go(amount, coins)
12+
13+
14+
def go(self, x: int, coins: List[int]) -> int:
15+
if x == 0:
16+
return 0
17+
18+
if self.dp[x] != -2:
19+
return self.dp[x]
20+
21+
mm = 100000
22+
23+
for coin in coins:
24+
if x - coin >= 0:
25+
sub = self.go(x - coin, coins)
26+
if (sub == -1): # 불가능 -> -1
27+
continue
28+
mm = min(mm, sub + 1)
29+
30+
self.dp[x] = mm if mm != 100000 else -1 # memoization
31+
32+
return self.dp[x]

combination-sum/Cyjin-jani.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// ! 나중에 다시 풀어야 할 문제
2+
//! 30분 내에 풀지 못해서 AI의 도움을 받아 구현했습니다..
3+
// recursion의 사용, 종료 조건 등 어느정도 근접한 아이디어를 구현했지만,
4+
// idx를 넘기지 않고 number를 직접 넘기려고 했던 부분이나, results pop을 놓쳤던 부분 등이 있습니다.
5+
const combinationSum = function (candidates, target) {
6+
const answer = [];
7+
8+
function recursion(idx, target, results = []) {
9+
if (target === 0) {
10+
answer.push([...results]);
11+
return;
12+
}
13+
if (target < 0) return;
14+
15+
for (let i = idx; i < candidates.length; i++) {
16+
results.push(candidates[i]);
17+
recursion(i, target - candidates[i], results);
18+
results.pop();
19+
}
20+
}
21+
recursion(0, target, []);
22+
23+
return answer;
24+
};

combination-sum/YOOHYOJEONG.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# https://leetcode.com/problems/combination-sum/
2+
3+
# for문으로 해결이 되지 않아 gpt 도움을 받아 해결하였습니다.
4+
# 같은 숫자를 재사용하면서, 순서를 고정해서 중복 없는 조합을 DFS로 탐색하는 구조
5+
# 시간 복잡도 : O(2^n) (백트래킹 탐색)
6+
# 공간 복잡도 : O(target) (재귀 깊이)
7+
8+
class Solution(object):
9+
def combinationSum(self, candidates, target):
10+
11+
result = []
12+
13+
def dfs(start, path, total):
14+
# 종료 조건 1 : target을 맞춘 경우
15+
if total == target:
16+
result.append(path[:])
17+
return
18+
19+
# 종료 조건 2 : target 초과한 경우
20+
if total > target:
21+
return
22+
23+
# 후보 탐색 -> 같은 방향으로만 탐색
24+
for i in range(start, len(candidates)):
25+
# 같은 숫자 재사용 가능 -> i를 그대로 넘기기
26+
dfs(i, path+[candidates[i]], total+candidates[i]) # 새로운 리스트 만들어서 전달
27+
28+
29+
dfs(0, [], 0)
30+
31+
return result

combination-sum/dohyeon2.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import java.util.ArrayList;
2+
import java.util.List;
3+
4+
class Solution {
5+
// TC : O(n!) => TC : O(2^T)
6+
// SC : O(n^2) => SC : O(T)
7+
ArrayList<List<Integer>> result = new ArrayList<>();
8+
9+
public List<List<Integer>> combinationSum(int[] candidates, int target) {
10+
backtrack(0, target, candidates, new ArrayList<>());
11+
return result;
12+
}
13+
14+
private void backtrack(int start, int diff, int[] candidates, ArrayList<Integer> path) {
15+
if (diff == 0) {
16+
result.add(new ArrayList<>(path)); // 깊은 복사
17+
return;
18+
}
19+
20+
if (diff < 0) {
21+
return;
22+
}
23+
24+
for (int i = start; i < candidates.length; i++) {
25+
path.add(candidates[i]);
26+
backtrack(i, diff - candidates[i], candidates, path);
27+
path.remove(path.size() - 1);
28+
}
29+
}
30+
}

combination-sum/gcount85.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""
2+
# Intuition
3+
backtracking
4+
5+
# Complexity
6+
- Time complexity: N을 깊이만큼 곱한다. 따라서 아래와 같을 때, O(N^(T/M))
7+
N = candidates 개수
8+
T = target
9+
M = candidates 중 최소값
10+
11+
- Space complexity: O(T/M)
12+
"""
13+
14+
15+
class Solution:
16+
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
17+
candidates.sort()
18+
answer = []
19+
output = []
20+
21+
def dfs(cur_i, cur_sum):
22+
if cur_sum == target:
23+
answer.append(output[:])
24+
return
25+
26+
for i in range(cur_i, len(candidates)):
27+
num = candidates[i]
28+
29+
if cur_sum + num > target:
30+
break
31+
32+
output.append(num)
33+
dfs(i, cur_sum + num)
34+
output.pop()
35+
36+
dfs(0, 0)
37+
return answer

combination-sum/grapefruit13.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
function combinationSum(candidates: number[], target: number): number[][] {
2+
const answer: number[][] = [];
3+
4+
function dfs(index: number, path: number[], sum: number) {
5+
if (sum === target) {
6+
answer.push([...path]);
7+
return;
8+
}
9+
if (sum > target) return;
10+
11+
for (let i = index; i < candidates.length; i++) {
12+
path.push(candidates[i]);
13+
dfs(i, path, sum + candidates[i]);
14+
path.pop();
15+
}
16+
}
17+
18+
dfs(0, [], 0);
19+
return answer;
20+
}

0 commit comments

Comments
 (0)