diff --git a/find-median-from-data-stream/hyer0705.ts b/find-median-from-data-stream/hyer0705.ts new file mode 100644 index 000000000..ecbd6a8ba --- /dev/null +++ b/find-median-from-data-stream/hyer0705.ts @@ -0,0 +1,50 @@ +class MedianFinder { + private left: PriorityQueue; + private right: PriorityQueue; + + constructor() { + this.left = new PriorityQueue((a, b) => b - a); // 최대 힙 + this.right = new PriorityQueue((a, b) => a - b); // 최소 힙 + } + + addNum(num: number): void { + if (this.left.isEmpty() || num <= this.left.front()) { + this.left.enqueue(num); + } else { + this.right.enqueue(num); + } + + if (this.left.size() > this.right.size() + 1) { + this.right.enqueue(this.left.dequeue()); + } + + if (this.right.size() > this.left.size()) { + this.left.enqueue(this.right.dequeue()); + } + + if (!this.right.isEmpty() && this.left.front() > this.right.front()) { + const maxValue = this.left.dequeue(); + + this.right.enqueue(maxValue); + } + } + + findMedian(): number { + let result = 0; + + if (this.left.size() === this.right.size()) { + result = (this.left.front() + this.right.front()) / 2; + } else if (this.left.size() === this.right.size() + 1) { + result = this.left.front(); + } + + return result; + } +} + +/** + * Your MedianFinder object will be instantiated and called as such: + * var obj = new MedianFinder() + * obj.addNum(num) + * var param_2 = obj.findMedian() + */ diff --git a/insert-interval/hyer0705.ts b/insert-interval/hyer0705.ts new file mode 100644 index 000000000..f96d7de7e --- /dev/null +++ b/insert-interval/hyer0705.ts @@ -0,0 +1,24 @@ +// Time Complexity: O(n) +// Space Complexity: O(n) +function insert(intervals: number[][], newInterval: number[]): number[][] { + const result: number[][] = []; + let merged = newInterval; + let i = 0; + + while (i < intervals.length && intervals[i][1] < merged[0]) { + result.push(intervals[i++]); + } + + while (i < intervals.length && intervals[i][0] <= merged[1]) { + merged[0] = Math.min(merged[0], intervals[i][0]); + merged[1] = Math.max(merged[1], intervals[i][1]); + i++; + } + result.push(merged); + + while (i < intervals.length && intervals[i][0] > merged[1]) { + result.push(intervals[i++]); + } + + return result; +} diff --git a/kth-smallest-element-in-a-bst/hyer0705.ts b/kth-smallest-element-in-a-bst/hyer0705.ts new file mode 100644 index 000000000..26a66275a --- /dev/null +++ b/kth-smallest-element-in-a-bst/hyer0705.ts @@ -0,0 +1,38 @@ +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + */ + +// Time Complexity: O(k) - 최악의 경우 모든 노드를 방문하면 O(n) +// Space Complexity: O(h) - 재귀 호출 스택의 최대 깊이 (h는 트리의 높이) +function kthSmallest(root: TreeNode | null, k: number): number { + let count = 0; + let result = 0; + + const inorder = (node: TreeNode | null): void => { + if (!node) return; + + inorder(node.left); + + count++; + if (count === k) { + result = node.val; + return; + } + + inorder(node.right); + }; + + inorder(root); + + return result; +} diff --git a/lowest-common-ancestor-of-a-binary-search-tree/hyer0705.ts b/lowest-common-ancestor-of-a-binary-search-tree/hyer0705.ts new file mode 100644 index 000000000..7e2cce5cb --- /dev/null +++ b/lowest-common-ancestor-of-a-binary-search-tree/hyer0705.ts @@ -0,0 +1,25 @@ +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + * + * Time Complexity: O(logn) in average, O(n) in the worst case + * Space Complexity: O(logn) in average, O(n) in the worst case + */ +function lowestCommonAncestor(root: TreeNode | null, p: TreeNode | null, q: TreeNode | null): TreeNode | null { + 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); + } + + return root; +} diff --git a/meeting-rooms/hyer0705.ts b/meeting-rooms/hyer0705.ts new file mode 100644 index 000000000..b30f28a97 --- /dev/null +++ b/meeting-rooms/hyer0705.ts @@ -0,0 +1,40 @@ +import { Interval } from "../home/lib/index"; +/** + * Definition of Interval: + * export class Interval { + * start :number; + * end :number; + * constructor(start :number, end :number) { + * this.start = start; + * this.end = end; + * } + * } + */ + +export class Solution { + /** + * Time Complexity: O(nlogn) + * Space Complexity: O(1) + * + * @param intervals: an array of meeting time intervals + * @return: if a person could attend all meetings + */ + canAttendMeetings(intervals: Interval[]): boolean { + if (intervals.length <= 1) return true; + + intervals.sort((a, b) => a.start - b.start); + + let prevEnd = intervals[0].end; + for (let i = 1; i < intervals.length; i++) { + const currentStart = intervals[i].start; + const currentEnd = intervals[i].end; + + if (prevEnd > currentStart) { + return false; + } + prevEnd = currentEnd; + } + + return true; + } +}