Skip to content

[clara-shin] Week 4 Solutions #1352

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 27, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
25 changes: 25 additions & 0 deletions coin-change/clara-shin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* 시간 복잡도: O(amount * coins.length)
* 각 금액에 대해 모든 동전을 고려해야 함
*/

/**
* @param {number[]} coins
* @param {number} amount
* @return {number}
*/
var coinChange = function (coins, amount) {
const dp = new Array(amount + 1).fill(Infinity);

dp[0] = 0; // 금액 0은 동전이 필요 없음

for (const coin of coins) {
for (let i = coin; i <= amount; i++) {
// dp[i] : 금액 i를 만들기 위한 최소 동전 개수
// dp[i - coin] + 1 : 현재 동전을 한 개 사용하고 나머지 금액(i - coin)을 만드는 최소 동전 개수
dp[i] = Math.min(dp[i], dp[i - coin] + 1);
}
}

return dp[amount] === Infinity ? -1 : dp[amount];
};
36 changes: 36 additions & 0 deletions find-minimum-in-rotated-sorted-array/clara-shin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* 오름차순으로 정렬된 배열이 1~n번 회전된 상태에서 최소값을 찾는 문제
* 문제 핵심:
* 1. 배열은 원래 오름차순으로 정렬되어 있었음
* 2. 그 배열이 1~n번 회전되었음
* 3. 최소값을 O(log n) 시간 복잡도로 찾아야 함
*
* => 이 문제는 회전된 배열에서 최소값을 찾아야 함
* => 최소값은 pivot 포인트(회전이 일어난 지점)에서 발견됨
*/

/**
* @param {number[]} nums - 회전된 정렬 배열
* @return {number} - 배열의 최소값
*/
var findMin = function (nums) {
let left = 0; // 검색범위의 시작 인덱스
let right = nums.length - 1; // 검색범위의 끝 인덱스

// 이진 탐색
while (left < right) {
const mid = Math.floor((left + right) / 2);

// 중간 값이 오른쪽 끝 값보다 크면, 최소값은 오른쪽에 있음
if (nums[mid] > nums[right]) {
left = mid + 1;
}
// 중간 값이 오른쪽 끝 값보다 작거나 같으면, 최소값은 왼쪽에 있음 (중간 포함)
else {
right = mid;
}
}

// 반복이 끝나면 left와 right는 같은 인덱스을 가리키고, 이 인덱스의 값(피봇포인트) = 최소값의 위치
return nums[left];
};
31 changes: 31 additions & 0 deletions maximum-depth-of-binary-tree/clara-shin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* 문제 요약: 이진 트리의 루트 노드가 주어질 때, 이 트리의 최대 깊이를 반환해야 한다
* 최대 깊이: 루트 노드에서 가장 먼 리프 노드까지의 경로에 있는 노드의 수
* 시간 복잡도: O(n) - 모든 노드를 한 번씩 방문
* 공간 복잡도: O(h) - h는 트리의 높이(최악의 경우 O(n)) - 재귀 호출 스택 사용
*/

/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var maxDepth = function (root) {
// 기저 조건: 노드가 없으면(empty tree) 깊이는 0
if (root === null) {
return 0;
}

const leftDepth = maxDepth(root.left);
const rightDepth = maxDepth(root.right);

// 현재 노드의 최대 깊이: 왼쪽과 오른쪽 서브트리의 최대 깊이 중 큰 값에 1을 더한 값
return Math.max(leftDepth, rightDepth) + 1;
};
46 changes: 46 additions & 0 deletions merge-two-sorted-lists/clara-shin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* 문제 정의
* 입력: 두 개의 정렬된 연결 리스트의 헤드 노드 list1과 list2
* 출력: 두 리스트를 병합한 정렬된 연결 리스트의 헤드 노드
* 조건: 두 리스트는 이미 오름차순으로 정렬되어 있음
*
* 접근 방법
* 1. 더미 헤드 노드를 생성하여 결과 리스트의 시작점을 설정
* 2. 두 리스트를 순회하며 작은 값을 가진 노드를 결과 리스트에 추가
* 3. 한 리스트가 끝나면 다른 리스트의 남은 노드를 결과 리스트에 연결
* 4. 더미 헤드의 다음 노드를 반환하여 결과 리스트를 반환
* 5. 시간 복잡도: O(n + m) (n: list1의 길이, m: list2의 길이)
* 공간 복잡도: O(1) (추가적인 공간 사용 없음)
*
* 재귀적으로 구현할 수도 있지만, 공간복잡도는 재귀호출 스택 때문에 O(n + m)이 됨
* 따라서, 반복적(iterative) 방법을 사용하여 공간복잡도를 O(1)로 유지하는 것이 좋음
*/

/**
* @param {ListNode} list1 - 첫 번째 정렬된 연결 리스트의 헤드
* @param {ListNode} list2 - 두 번째 정렬된 연결 리스트의 헤드
* @return {ListNode} - 병합된 정렬 리스트의 헤드
*/
var mergeTwoLists = function (list1, list2) {
let dummy = new ListNode(-1); // 더미 헤드 노드 생성 (결과 리스트의 시작점)

let current = dummy; // 현재 결과 리스트의 위치를 추적하는 포인터

while (list1 !== null && list2 !== null) {
if (list1.val <= list2.val) {
current.next = list1;
list1 = list1.next;
} else {
current.next = list2;
list2 = list2.next;
}
// 결과 리스트의 포인터 이동ㄱㄱ
current = current.next;
}

// 남아있는 노드들을 결과 리스트에 연결 (list1이나 list2 중 하나는 이미 null일 테니까)
current.next = list1 !== null ? list1 : list2;

// 더미 헤드 다음 노드가 실제 결과의 시작 노드가 됨
return dummy.next;
};