diff --git a/course-schedule/clara-shin.js b/course-schedule/clara-shin.js new file mode 100644 index 000000000..0f5c98998 --- /dev/null +++ b/course-schedule/clara-shin.js @@ -0,0 +1,45 @@ +/** + * @param {number} numCourses + * @param {number[][]} prerequisites + * @return {boolean} + */ +var canFinish = function (numCourses, prerequisites) { + // 1. 인접 리스트와 진입 차수 배열 초기화 + const graph = new Array(numCourses).fill(null).map(() => []); + const inDegree = new Array(numCourses).fill(0); + + // 2. 그래프 구성 및 진입 차수 계산 + for (const [course, prereq] of prerequisites) { + graph[prereq].push(course); + inDegree[course]++; // course의 진입 차수 증가 + } + + // 3. 진입 차수가 0인 노드들을 큐에 추가 + const queue = []; + for (let i = 0; i < numCourses; i++) { + if (inDegree[i] === 0) { + queue.push(i); + } + } + + // 4. 위상 정렬 수행 + let processedCourses = 0; + + while (queue.length > 0) { + const current = queue.shift(); + processedCourses++; + + // 현재 노드와 연결된 모든 노드의 진입 차수 감소 + for (const neighbor of graph[current]) { + inDegree[neighbor]--; + + // 진입 차수가 0이 되면 큐에 추가 + if (inDegree[neighbor] === 0) { + queue.push(neighbor); + } + } + } + + // 5. 모든 강의를 처리했는지 확인 + return processedCourses === numCourses; +}; diff --git a/invert-binary-tree/clara-shin.js b/invert-binary-tree/clara-shin.js new file mode 100644 index 000000000..530ff05bb --- /dev/null +++ b/invert-binary-tree/clara-shin.js @@ -0,0 +1,30 @@ +/** + * 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 {TreeNode} + */ +var invertTree = function (root) { + if (!root) return null; + + const queue = [root]; + + while (queue.length > 0) { + const current = queue.shift(); + + // 자식 노드들 바꾸기 + [current.left, current.right] = [current.right, current.left]; + + // 자식 노드들을 큐에 추가 + if (current.left) queue.push(current.left); + if (current.right) queue.push(current.right); + } + + return root; +}; diff --git a/jump-game/clara-shin.js b/jump-game/clara-shin.js new file mode 100644 index 000000000..815b2e9e5 --- /dev/null +++ b/jump-game/clara-shin.js @@ -0,0 +1,19 @@ +/** + * @param {number[]} nums + * @return {boolean} + */ +var canJump = function (nums) { + let farthest = 0; + + for (let i = 0; i < nums.length; i++) { + // 현재 위치가 지금까지 갈 수 있는 가장 먼 거리보다 멀다면 + if (i > farthest) { + return false; // 도달 불가능 + } + + // 현재 위치에서 갈 수 있는 가장 먼 거리 업데이트 + farthest = Math.max(farthest, i + nums[i]); + } + + return true; +}; diff --git a/merge-k-sorted-lists/clara-shin.js b/merge-k-sorted-lists/clara-shin.js new file mode 100644 index 000000000..9822dcc16 --- /dev/null +++ b/merge-k-sorted-lists/clara-shin.js @@ -0,0 +1,54 @@ +/** + * Definition for singly-linked list. + * function ListNode(val, next) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + */ +/** + * @param {ListNode[]} lists + * @return {ListNode} + */ +// 최적화된 K개 연결 리스트 병합 - 재귀 분할 정복 +var mergeKLists = function (lists) { + if (!lists || lists.length === 0) return null; + if (lists.length === 1) return lists[0]; + + return mergeListsRange(lists, 0, lists.length - 1); +}; + +// 범위 내의 리스트들을 재귀적으로 병합 +function mergeListsRange(lists, start, end) { + // 기저 조건: 하나의 리스트만 남은 경우 + if (start === end) { + return lists[start]; + } + + // 두 개의 리스트만 남은 경우 + if (start + 1 === end) { + return mergeTwoLists(lists[start], lists[end]); + } + + // 중간점을 기준으로 분할 + let mid = Math.floor((start + end) / 2); + let left = mergeListsRange(lists, start, mid); + let right = mergeListsRange(lists, mid + 1, end); + + return mergeTwoLists(left, right); +} + +// 두 개의 정렬된 연결 리스트를 병합 (최적화) +function mergeTwoLists(l1, l2) { + // null 체크를 먼저 수행하여 불필요한 연산 방지 + if (!l1) return l2; + if (!l2) return l1; + + // 더 작은 값을 가진 노드를 선택하고 재귀 호출 + if (l1.val <= l2.val) { + l1.next = mergeTwoLists(l1.next, l2); + return l1; + } else { + l2.next = mergeTwoLists(l1, l2.next); + return l2; + } +} diff --git a/search-in-rotated-sorted-array/clara-shin.js b/search-in-rotated-sorted-array/clara-shin.js new file mode 100644 index 000000000..e56df706c --- /dev/null +++ b/search-in-rotated-sorted-array/clara-shin.js @@ -0,0 +1,39 @@ +/** + * @param {number[]} nums + * @param {number} target + * @return {number} + */ +var search = function (nums, target) { + let left = 0; + let right = nums.length - 1; + + while (left <= right) { + const mid = Math.floor((left + right) / 2); + + // 타겟을 찾았다면 인덱스 반환 + if (nums[mid] === target) { + return mid; + } + + // 왼쪽 절반이 정렬되어 있는 경우 + if (nums[left] <= nums[mid]) { + // 타겟이 왼쪽 정렬된 범위에 있는지 확인 + if (nums[left] <= target && target < nums[mid]) { + right = mid - 1; // 왼쪽으로 이동 + } else { + left = mid + 1; // 오른쪽으로 이동 + } + } + // 오른쪽 절반이 정렬되어 있는 경우 + else { + // 타겟이 오른쪽 정렬된 범위에 있는지 확인 + if (nums[mid] < target && target <= nums[right]) { + left = mid + 1; // 오른쪽으로 이동 + } else { + right = mid - 1; // 왼쪽으로 이동 + } + } + } + + return -1; // 타겟을 찾지 못함 +};