From 9be4f2bdf920dc82318bd739df6a987ed0a4acc4 Mon Sep 17 00:00:00 2001 From: Hyejin Date: Mon, 21 Apr 2025 23:51:18 +0900 Subject: [PATCH 1/4] Merge Two Sorted Lists solution --- merge-two-sorted-lists/clara-shin.js | 46 ++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 merge-two-sorted-lists/clara-shin.js diff --git a/merge-two-sorted-lists/clara-shin.js b/merge-two-sorted-lists/clara-shin.js new file mode 100644 index 000000000..00d4ffee9 --- /dev/null +++ b/merge-two-sorted-lists/clara-shin.js @@ -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; +}; From 2c306f390642ef387c4eba58c47e0d9805ca8f24 Mon Sep 17 00:00:00 2001 From: Hyejin Date: Thu, 24 Apr 2025 00:40:23 +0900 Subject: [PATCH 2/4] Maximum Depth of Binary Tree solution --- maximum-depth-of-binary-tree/clara-shin.js | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 maximum-depth-of-binary-tree/clara-shin.js diff --git a/maximum-depth-of-binary-tree/clara-shin.js b/maximum-depth-of-binary-tree/clara-shin.js new file mode 100644 index 000000000..9e93282bf --- /dev/null +++ b/maximum-depth-of-binary-tree/clara-shin.js @@ -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; +}; From 713ac160410d36a60bfdbe06b1810b0f23a858ea Mon Sep 17 00:00:00 2001 From: Hyejin Date: Thu, 24 Apr 2025 00:57:28 +0900 Subject: [PATCH 3/4] Find Minimum in Rotated Sorted Array solution --- .../clara-shin.js | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 find-minimum-in-rotated-sorted-array/clara-shin.js diff --git a/find-minimum-in-rotated-sorted-array/clara-shin.js b/find-minimum-in-rotated-sorted-array/clara-shin.js new file mode 100644 index 000000000..853324240 --- /dev/null +++ b/find-minimum-in-rotated-sorted-array/clara-shin.js @@ -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]; +}; From e3570f2690f61fc4d90a26814cd48fee16af47d9 Mon Sep 17 00:00:00 2001 From: Hyejin Date: Thu, 24 Apr 2025 01:05:34 +0900 Subject: [PATCH 4/4] Coin Change solution --- coin-change/clara-shin.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 coin-change/clara-shin.js diff --git a/coin-change/clara-shin.js b/coin-change/clara-shin.js new file mode 100644 index 000000000..fc95b04ad --- /dev/null +++ b/coin-change/clara-shin.js @@ -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]; +};