Skip to content

Commit 05ff95f

Browse files
authored
Merge branch 'DaleStudy:main' into main
2 parents 7d30fcb + e0c4f4c commit 05ff95f

Some content is hidden

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

46 files changed

+1251
-0
lines changed

3sum/soobing2.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* 문제 유형
3+
* - Array (정렬 + 투포인터)
4+
*
5+
* 문제 설명
6+
* - 3개의 수를 더해서 0이 되는 경우를 찾아서 배열로 반환하기
7+
*
8+
* 아이디어
9+
* 1) 정렬 후 투포인터 사용, 중복 제거
10+
11+
*/
12+
function threeSum(nums: number[]): number[][] {
13+
const result: number[][] = [];
14+
15+
// sorting
16+
nums.sort((a, b) => a - b);
17+
18+
for (let i = 0; i < nums.length - 2; i++) {
19+
// 중복 제거
20+
if (i > 0 && nums[i] === nums[i - 1]) continue;
21+
22+
let left = i + 1;
23+
let right = nums.length - 1;
24+
while (left < right) {
25+
const sum = nums[i] + nums[left] + nums[right];
26+
if (sum === 0) {
27+
result.push([nums[i], nums[left], nums[right]]);
28+
left++;
29+
right--;
30+
31+
// 중복 제거
32+
while (left < right && nums[left] === nums[left - 1]) left++;
33+
while (left < right && nums[right] === nums[right + 1]) right--;
34+
} else if (sum < 0) {
35+
left++;
36+
} else {
37+
right--;
38+
}
39+
}
40+
}
41+
return result;
42+
}

climbing-stairs/soobing.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* 문제 유형
3+
* - DP (피보나치)
4+
*
5+
* 문제 설명
6+
* - 계단을 올라가는 방법의 수를 구하기
7+
*
8+
* 아이디어
9+
* 1) 피보나치 수열 활용
10+
* - climbStairs(n) = climbStairs(n-1) + climbStairs(n-2)
11+
*/
12+
function climbStairsBottomUp(n: number): number {
13+
function fibonacci(n: number, memo = new Map<number, number>()) {
14+
if (n === 1) return 1;
15+
if (n === 2) return 2;
16+
17+
if (memo.has(n)) return memo.get(n);
18+
const result = fibonacci(n - 1, memo) + fibonacci(n - 2, memo);
19+
memo.set(n, result);
20+
return result;
21+
}
22+
return fibonacci(n);
23+
}
24+
25+
function climbStairsTopDown(n: number): number {
26+
const dp = new Array(n + 1).fill(0);
27+
dp[1] = 1;
28+
dp[2] = 2;
29+
30+
for (let i = 3; i <= n; i++) {
31+
dp[i] = dp[i - 1] + dp[i - 2];
32+
}
33+
return dp[n];
34+
}

combination-sum/delight010.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Solution {
2+
func combinationSum(_ candidates: [Int], _ target: Int) -> [[Int]] {
3+
var result: [[Int]] = []
4+
var current: [Int] = []
5+
findCombination(0, target, candidates, &current, &result)
6+
return result
7+
}
8+
9+
func findCombination(_ index: Int, _ target: Int, _ candidates: [Int], _ current: inout [Int], _ result: inout [[Int]]) {
10+
if target == 0 {
11+
result.append(current)
12+
return
13+
}
14+
15+
for i in index..<candidates.count {
16+
if candidates[i] <= target {
17+
current.append(candidates[i])
18+
findCombination(i, target - candidates[i], candidates, &current, &result)
19+
current.removeLast()
20+
}
21+
}
22+
}
23+
}
24+

combination-sum/hoyeongkwak.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
'''
2+
Time complexity : O(n ^ (target / min_val))
3+
Space complexity : O(target / min_val)
4+
backtracking
5+
c = [2], total = 2
6+
c = [2, 2], total = 4
7+
c = [2, 2, 2] total = 6
8+
c = [2, 2, 2, 2] total = 8, 초과 backtrack
9+
c = [2, 2, 2, 3] total = 9, 초과 backtrack
10+
c = [2, 2, 2, 6] total = 12, 초과 backtrack
11+
c = [2, 2, 2, 7] total = 13, 초과 backtrack
12+
c = [2, 2, 3] total = 7 정답 추가
13+
c = [2, 2, 6] total = 10, 초과 backtrack
14+
c = [2, 2, 7] total = 11, 초과 backtrack
15+
....
16+
[2,2,3], [7]
17+
18+
'''
19+
20+
class Solution:
21+
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
22+
result = []
23+
24+
def backtrack(start, current, total):
25+
if total == target:
26+
result.append(list(current))
27+
return
28+
if total > target:
29+
return
30+
31+
for i in range(start, len(candidates)):
32+
current.append(candidates[i])
33+
backtrack(i, current, total + candidates[i])
34+
current.pop()
35+
backtrack(0, [], 0)
36+
return result

combination-sum/hu6r1s.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
class Solution:
2+
"""
3+
시간 복잡도 (Time Complexity):
4+
- 이 문제는 백트래킹(DFS) 기반으로 모든 가능한 조합을 탐색합니다.
5+
- 최악의 경우 각 조합에서 한 숫자를 여러 번 사용할 수 있으므로, 트리의 깊이는 최대 target // min(candidates)
6+
- 각 깊이마다 최대 len(candidates)만큼 분기 가능
7+
- 따라서 시간 복잡도는 지수적으로 증가: O(2^T), T = target
8+
(정확한 upper bound는 계산하기 어렵지만, 대략적으로는 O(2^T) 또는 O(k^T)로 볼 수 있음)
9+
10+
공간 복잡도 (Space Complexity):
11+
- 재귀 호출의 최대 깊이: O(T), T = target (가장 작은 숫자만 반복해서 사용하는 경우)
12+
- 경로 저장용 리스트(nums): O(T)
13+
- 결과 저장용 리스트(output): 최악의 경우 모든 가능한 조합 저장 → O(number of valid combinations * 평균 길이)
14+
최종 공간 복잡도: **O(T + R)**,
15+
T: 재귀 깊이 / R: 결과 조합 수가 클 경우 output이 차지하는 공간
16+
17+
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
18+
output, nums = [], []
19+
20+
def dfs(start, total):
21+
if total > target:
22+
return
23+
if total == target:
24+
output.append(nums[:])
25+
26+
for i in range(start, len(candidates)):
27+
nums.append(candidates[i])
28+
dfs(i, total + candidates[i])
29+
nums.pop()
30+
31+
dfs(0, 0)
32+
return output
33+
"""
34+
"""
35+
2. dp
36+
dp[i]는 숫자들을 더해서 합이 i가 되는 모든 조합들을 저장합니다.
37+
dp[num - candidate]에 있는 조합에 candidate를 추가하면 num을 만들 수 있으므로 확장합니다.
38+
중복된 조합을 방지하기 위해 candidates를 바깥 루프에 둠 (즉, 같은 숫자를 계속 재사용하되, 이전 숫자부터 누적).
39+
40+
시간 복잡도 (Time Complexity):
41+
바깥 루프: 후보 숫자만큼 → O(N)
42+
안쪽 루프: target까지 반복 → O(T)
43+
가장 안쪽 루프: dp[num - candidate]에 있는 조합들을 모두 순회 → O(A) (A는 조합 개수 및 길이에 비례)
44+
→ 따라서 최악의 경우 O(N × T × A)
45+
46+
공간 복잡도 (Space Complexity):
47+
dp 배열 크기: target + 1 → O(T)
48+
각 dp[i]에 저장된 조합 리스트들의 개수와 길이 → O(A)
49+
따라서 전체 공간은 O(T × A)
50+
51+
Example 2의 dp 출력:
52+
53+
[[[]], [], [[2]], [], [], [], [], [], []]
54+
[[[]], [], [[2]], [], [[2, 2]], [], [], [], []]
55+
[[[]], [], [[2]], [], [[2, 2]], [], [[2, 2, 2]], [], []]
56+
[[[]], [], [[2]], [], [[2, 2]], [], [[2, 2, 2]], [], [[2, 2, 2, 2]]]
57+
[[[]], [], [[2]], [[3]], [[2, 2]], [], [[2, 2, 2]], [], [[2, 2, 2, 2]]]
58+
[[[]], [], [[2]], [[3]], [[2, 2]], [[2, 3]], [[2, 2, 2]], [], [[2, 2, 2, 2]]]
59+
[[[]], [], [[2]], [[3]], [[2, 2]], [[2, 3]], [[2, 2, 2], [3, 3]], [], [[2, 2, 2, 2]]]
60+
[[[]], [], [[2]], [[3]], [[2, 2]], [[2, 3]], [[2, 2, 2], [3, 3]], [[2, 2, 3]], [[2, 2, 2, 2]]]
61+
[[[]], [], [[2]], [[3]], [[2, 2]], [[2, 3]], [[2, 2, 2], [3, 3]], [[2, 2, 3]], [[2, 2, 2, 2], [2, 3, 3]]]
62+
[[[]], [], [[2]], [[3]], [[2, 2]], [[2, 3], [5]], [[2, 2, 2], [3, 3]], [[2, 2, 3]], [[2, 2, 2, 2], [2, 3, 3]]]
63+
[[[]], [], [[2]], [[3]], [[2, 2]], [[2, 3], [5]], [[2, 2, 2], [3, 3]], [[2, 2, 3], [2, 5]], [[2, 2, 2, 2], [2, 3, 3]]]
64+
[[[]], [], [[2]], [[3]], [[2, 2]], [[2, 3], [5]], [[2, 2, 2], [3, 3]], [[2, 2, 3], [2, 5]], [[2, 2, 2, 2], [2, 3, 3], [3, 5]]]
65+
"""
66+
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
67+
dp = [[] for _ in range(target + 1)]
68+
dp[0] = [[]]
69+
70+
for candidate in candidates:
71+
for num in range(candidate, target + 1):
72+
for combination in dp[num - candidate]:
73+
dp[num].append(combination + [candidate])
74+
return dp[target]

combination-sum/hyunjung-choi.kt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
class Solution {
2+
fun combinationSum(candidates: IntArray, target: Int): List<List<Int>> {
3+
val result = mutableListOf<List<Int>>()
4+
val currentCombination = mutableListOf<Int>()
5+
6+
candidates.sort()
7+
8+
backtrack(candidates, target, 0, currentCombination, result)
9+
10+
return result
11+
}
12+
13+
private fun backtrack(
14+
candidates: IntArray,
15+
remainingTarget: Int,
16+
startIndex: Int,
17+
currentCombination: MutableList<Int>,
18+
result: MutableList<List<Int>>
19+
) {
20+
if (remainingTarget == 0) {
21+
result.add(currentCombination.toList())
22+
return
23+
}
24+
25+
if (remainingTarget < 0) {
26+
return
27+
}
28+
29+
for (i in startIndex until candidates.size) {
30+
val candidate = candidates[i]
31+
32+
if (candidate > remainingTarget) {
33+
break
34+
}
35+
36+
currentCombination.add(candidate)
37+
38+
backtrack(candidates, remainingTarget - candidate, i, currentCombination, result)
39+
40+
currentCombination.removeAt(currentCombination.size - 1)
41+
}
42+
}
43+
}

combination-sum/jinvicky.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import java.util.ArrayList;
2+
import java.util.List;
3+
4+
class Solution {
5+
public List<List<Integer>> combinationSum(int[] candidates, int target) {
6+
List<List<Integer>> answer = new ArrayList<>();
7+
8+
makeCombination(candidates, target, 0, new ArrayList<>(), 0, answer);
9+
return answer;
10+
}
11+
12+
private void makeCombination(int[] candidates,
13+
int target,
14+
int idx,
15+
List<Integer> comb,
16+
int total,
17+
List<List<Integer>> res) {
18+
if (total == target) {
19+
res.add(new ArrayList<>(comb));
20+
return;
21+
}
22+
23+
if (total > target || idx >= candidates.length) {
24+
return;
25+
}
26+
27+
comb.add(candidates[idx]);
28+
makeCombination(candidates, target, idx, comb, total + candidates[idx], res);
29+
comb.remove(comb.size() - 1);
30+
makeCombination(candidates, target, idx + 1, comb, total, res);
31+
}
32+
}

combination-sum/mkwkw.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
//set-up

combination-sum/ohgyulim.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import java.util.*;
2+
3+
class Solution {
4+
List<List<Integer>> answer = new ArrayList<>();
5+
public List<List<Integer>> combinationSum(int[] candidates, int target) {
6+
Arrays.sort(candidates);
7+
recur(new ArrayList<Integer>(), candidates, target, 0, 0);
8+
return answer;
9+
}
10+
11+
public void recur(List<Integer> result, int[] candidates, int target, int sum, int index) {
12+
if (sum == target) {
13+
List<Integer> deepCopyRes = new ArrayList<>(result);
14+
answer.add(deepCopyRes);
15+
return;
16+
}
17+
for (int i = index; i < candidates.length; i++) {
18+
if (sum + candidates[i] <= target) {
19+
result.add(candidates[i]);
20+
recur(result, candidates, target, sum + candidates[i], i);
21+
result.remove(Integer.valueOf(candidates[i]));
22+
}
23+
}
24+
}
25+
}

decode-ways/delight010.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class Solution {
2+
func numDecodings(_ s: String) -> Int {
3+
var array = Array(s)
4+
var dp: [Int: Int] = [array.count: 1]
5+
for i in stride(from: array.count - 1, to: -1, by: -1) {
6+
if array[i] == "0" {
7+
dp[i] = 0
8+
} else {
9+
dp[i] = dp[i + 1]
10+
}
11+
12+
if i + 1 < array.count && (array[i] == "1" || array[i] == "2" && "0123456".contains(array[i + 1])) {
13+
dp[i, default: 0] += dp[i + 2] ?? 0
14+
}
15+
}
16+
return dp[0]!
17+
}
18+
}
19+

0 commit comments

Comments
 (0)