From 9f871538fcf0252303112b6c053f927593981f8a Mon Sep 17 00:00:00 2001 From: Finn <82873315+uraflower@users.noreply.github.com> Date: Mon, 23 Jun 2025 17:31:37 +0900 Subject: [PATCH 1/5] [ PS ] : Meeting Rooms --- meeting-rooms/uraflower.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 meeting-rooms/uraflower.js diff --git a/meeting-rooms/uraflower.js b/meeting-rooms/uraflower.js new file mode 100644 index 000000000..adb707e58 --- /dev/null +++ b/meeting-rooms/uraflower.js @@ -0,0 +1,20 @@ +/** + * @param intervals: an array of meeting time intervals + * @return: if a person could attend all meetings + */ +const canAttendMeetings = function (intervals) { + intervals.sort((a, b ) => a[0] - b[0]); // 시작 시간 기준으로 오름차순 정렬 + + let prevEnd = intervals[0][1]; + for (const [start, end] of intervals) { + if (start < prevEnd) { + return false; + } + prevEnd = end; + } + + return true; +} + +// 시간복잡도: O(n * log n) +// 공간복잡도: O(1) From 287c0453417875f4052923cbaaf98f819bc1f55a Mon Sep 17 00:00:00 2001 From: Finn <82873315+uraflower@users.noreply.github.com> Date: Wed, 25 Jun 2025 12:06:25 +0900 Subject: [PATCH 2/5] [ PS ] : Lowest Common Ancestor of a Binary Search Tree --- .../uraflower.js | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 lowest-common-ancestor-of-a-binary-search-tree/uraflower.js diff --git a/lowest-common-ancestor-of-a-binary-search-tree/uraflower.js b/lowest-common-ancestor-of-a-binary-search-tree/uraflower.js new file mode 100644 index 000000000..e28905921 --- /dev/null +++ b/lowest-common-ancestor-of-a-binary-search-tree/uraflower.js @@ -0,0 +1,28 @@ +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @param {TreeNode} p + * @param {TreeNode} q + * @return {TreeNode} + */ +const lowestCommonAncestor = function (root, p, q) { + // 이진탐색트리(BST)의 특징을 활용하여 + // p, q의 값과 root 값을 비교해 p, q가 속한 트리(left/right)를 판단 + if (p.val < root.val && q.val < root.val) { + return lowestCommonAncestor(root.left, p, q); + } else if (p.val > root.val && q.val > root.val) { + return lowestCommonAncestor(root.right, p, q); + } else { + return root; + } +}; + +// 시간복잡도: O(h) (h: 트리의 높이, 즉 재귀 스택 깊이) +// 공간복잡도: O(h) (h: 트리의 높이, 즉 재귀 스택 깊이) From 04bdf432fa970266d04795ab29501e3250e749a0 Mon Sep 17 00:00:00 2001 From: Finn <82873315+uraflower@users.noreply.github.com> Date: Wed, 25 Jun 2025 12:26:54 +0900 Subject: [PATCH 3/5] [ PS ] : Kth Smallest Element in a BST --- kth-smallest-element-in-a-bst/uraflower.js | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 kth-smallest-element-in-a-bst/uraflower.js diff --git a/kth-smallest-element-in-a-bst/uraflower.js b/kth-smallest-element-in-a-bst/uraflower.js new file mode 100644 index 000000000..85a9d158e --- /dev/null +++ b/kth-smallest-element-in-a-bst/uraflower.js @@ -0,0 +1,29 @@ +/** + * 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 + * @param {number} k + * @return {number} + */ +const kthSmallest = function (root, k) { + const sorted = []; + + const traverse = function (root) { + if (!root) return; + traverse(root.left); + sorted.push(root.val); + traverse(root.right); + } + + traverse(root); + return sorted[k - 1]; +}; + +// 시간복잡도: O(n) +// 공간복잡도: O(n) (배열) From f45d2fb77feb577bf2a6f9b40c56f04f370e556b Mon Sep 17 00:00:00 2001 From: Finn <82873315+uraflower@users.noreply.github.com> Date: Fri, 27 Jun 2025 17:57:11 +0900 Subject: [PATCH 4/5] [ PS ] : Insert Interval --- insert-interval/uraflower.js | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 insert-interval/uraflower.js diff --git a/insert-interval/uraflower.js b/insert-interval/uraflower.js new file mode 100644 index 000000000..a718afcb6 --- /dev/null +++ b/insert-interval/uraflower.js @@ -0,0 +1,34 @@ +/** + * @param {number[][]} intervals + * @param {number[]} newInterval + * @return {number[][]} + */ +const insert = function(intervals, newInterval) { + const merged = []; + let i = 0; + + // 겹치지 않는 앞부분 push + while (i < intervals.length && intervals[i][1] < newInterval[0]) { + merged.push(intervals[i]); + i++; + } + + // 겹치는 부분 처리 + while (i < intervals.length && intervals[i][0] <= newInterval[1]) { + newInterval[0] = Math.min(newInterval[0], intervals[i][0]); + newInterval[1] = Math.max(newInterval[1], intervals[i][1]); + i++; + } + merged.push(newInterval); + + // 겹치지 않는 뒷부분 push + while (i < intervals.length) { + merged.push(intervals[i]); + i++; + } + + return merged; +}; + +// 시간복잡도: O(n) +// 공간복잡도: O(n) (반환할 배열) From 499d1987339e318ce76842f6c28f627bfef3763d Mon Sep 17 00:00:00 2001 From: Finn <82873315+uraflower@users.noreply.github.com> Date: Fri, 27 Jun 2025 19:06:08 +0900 Subject: [PATCH 5/5] [ PS ] : Find Median from Data Stream --- find-median-from-data-stream/uraflower.js | 72 +++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 find-median-from-data-stream/uraflower.js diff --git a/find-median-from-data-stream/uraflower.js b/find-median-from-data-stream/uraflower.js new file mode 100644 index 000000000..75385bacb --- /dev/null +++ b/find-median-from-data-stream/uraflower.js @@ -0,0 +1,72 @@ +// 배열 + 이분 탐색 삽입 (정렬) 로 풀이함 + +// 다른 방식으로는 듀얼 힙을 사용하는 게 있음 (성능 면에서 더 우수함) +// 최소힙, 최대힙 두 개를 두고 나눠서 add 이 때 size 차이는 1 이하여야 함 +// ex. 1 2 3 4 5 6 => 최대 힙에 1 2 3, 최소 힙에 4 5 6 => (3 + 4) / 2 +// ex. 2 3 4 => 최대 힙에 2 3, 최소 힙에 4 => 3 +// 참고로 leetcode에서 JS를 위한 MaxPriorityQueue와 같은 자료구조를 제공하는 듯 한데... +// 메서드를 어디서 볼 수 있는지 모르겠음 + +class MedianFinder { + constructor() { + this.nums = []; + } + + /** + * 시간복잡도: O(n) (이분탐색: log n, splice: n) + * 공간복잡도: O(1) + * @param {number} num + * @return {void} + */ + addNum(num) { + const i = this.#findInsertPosition(num); + this.nums.splice(i, 0, num); + } + + /** + * 이진 탐색으로 삽입 지점 찾는 함수 + * 시간복잡도: O(log n) + * 공간복잡도: O(1) + */ + #findInsertPosition(num) { + let left = 0; + let right = this.nums.length; + + while (left <= right) { + const mid = Math.floor((left + right) / 2); + + if (num < this.nums[mid]) { + right = mid - 1; + } else if (this.nums[mid] < num) { + left = mid + 1; + } else { + return mid; + } + } + + return left; + } + + /** + * 시간복잡도: O(1) + * 공간복잡도: O(1) + * @return {number} + */ + findMedian() { + const len = this.nums.length; + const midIndex = Math.floor(len / 2); + + if (len % 2 === 0) { + return (this.nums[midIndex - 1] + this.nums[midIndex]) / 2; + } else { + return this.nums[midIndex]; + } + } +}; + +/** + * Your MedianFinder object will be instantiated and called as such: + * var obj = new MedianFinder() + * obj.addNum(num) + * var param_2 = obj.findMedian() + */