Skip to content

[HoonDongKang] Week 13 Solutions #1611

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 5 commits into from
Jun 28, 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
127 changes: 127 additions & 0 deletions find-median-from-data-stream/HoonDongKang.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/**
* [Problem]: [295] Find Median from Data Stream
* (https://leetcode.com/problems/find-median-from-data-stream/description/)
*/
class Heap {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MinHeap, MaxHeap을 따로 구현하고 나서 든 생각이 하나도 합쳐도 되지 않을까였는데... 이렇게 구현하는군요! 👍

private numbers: number[];
private compare: (a: number, b: number) => boolean;

constructor(compare: (a: number, b: number) => boolean) {
this.numbers = [];
this.compare = compare;
}

private getParentIdx(index: number) {
return Math.floor((index - 1) / 2);
}

private getLeftChildIdx(index: number) {
return 2 * index + 1;
}

private getRightChildIdx(index: number) {
return 2 * index + 2;
}

private swap(index1: number, index2: number): void {
[this.numbers[index1], this.numbers[index2]] = [this.numbers[index2], this.numbers[index1]];
}

private heapifyUp(index: number) {
const parentIndex = this.getParentIdx(index);
if (0 <= parentIndex && this.compare(this.numbers[index], this.numbers[parentIndex])) {
this.swap(index, parentIndex);
this.heapifyUp(parentIndex);
}
}

private heapifyDown(index: number): void {
const leftChildIndex = this.getLeftChildIdx(index);
const rightChildIndex = this.getRightChildIdx(index);
let largestIndex = index;

if (
leftChildIndex < this.numbers.length &&
this.compare(this.numbers[leftChildIndex], this.numbers[largestIndex])
) {
largestIndex = leftChildIndex;
}

if (
rightChildIndex < this.numbers.length &&
this.compare(this.numbers[rightChildIndex], this.numbers[largestIndex])
) {
largestIndex = rightChildIndex;
}

if (largestIndex !== index) {
this.swap(index, largestIndex);
this.heapifyDown(largestIndex);
}
}

insert(number: number) {
this.numbers.push(number);
this.heapifyUp(this.numbers.length - 1);
}

pop() {
if (this.numbers.length === 0) {
return null;
}

if (this.numbers.length === 1) {
return this.numbers.pop()!;
}

const root = this.numbers[0];
this.numbers[0] = this.numbers.pop()!;
this.heapifyDown(0);

return root;
}

peek() {
return this.numbers.length > 0 ? this.numbers[0] : null;
}

size(): number {
return this.numbers.length;
}
}

class MedianFinder {
private smallHeap: Heap;
private largeHeap: Heap;

constructor() {
this.smallHeap = new Heap((a, b) => a > b);
this.largeHeap = new Heap((a, b) => a < b);
}

//시간복잡도 O(log n)
addNum(num: number): void {
this.smallHeap.insert(num);
this.largeHeap.insert(this.smallHeap.pop()!);

if (this.smallHeap.size() < this.largeHeap.size()) {
this.smallHeap.insert(this.largeHeap.pop()!);
}
}

//시간복잡도 O(1)
findMedian(): number {
if (this.smallHeap.size() > this.largeHeap.size()) {
return this.smallHeap.peek()!;
} else {
return (this.smallHeap.peek()! + this.largeHeap.peek()!) / 2;
}
}
}

/**
* Your MedianFinder object will be instantiated and called as such:
* var obj = new MedianFinder()
* obj.addNum(num)
* var param_2 = obj.findMedian()
*/
34 changes: 34 additions & 0 deletions insert-interval/HoonDongKang.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* [Problem]: [57] Insert Interval
* (https://leetcode.com/problems/insert-interval/)
*/

//시간복잡도 O(n)
//공간복잡도 O(n)
function insert(intervals: number[][], newInterval: number[]): number[][] {
const result: number[][] = [];

let idx = 0;

while (idx < intervals.length && intervals[idx][1] < newInterval[0]) {
result.push(intervals[idx]);
idx++;
}

while (idx < intervals.length && intervals[idx][0] <= newInterval[1]) {
newInterval = [
Math.min(intervals[idx][0], newInterval[0]),
Math.max(intervals[idx][1], newInterval[1]),
];
idx++;
}

result.push(newInterval);

while (idx < intervals.length) {
result.push(intervals[idx]);
idx++;
}

return result;
}
34 changes: 34 additions & 0 deletions kth-smallest-element-in-a-bst/HoonDongKang.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* [Problem]: [230] Kth Smallest Element in a BST
* (https://leetcode.com/problems/kth-smallest-element-in-a-bst/description/)
*/

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;
}
}

function kthSmallest(root: TreeNode | null, k: number): number {
//시간복잡도 O(n)
//공간복잡도 O(n)
function inOrderFunc(root: TreeNode | null, k: number): number {
const values: number[] = [];

function dfs(node: TreeNode | null) {
if (!node) return;
dfs(node.left);
values.push(node.val);
dfs(node.right);
}

dfs(root);

return values[k - 1];
}
}
63 changes: 63 additions & 0 deletions lowest-common-ancestor-of-a-binary-search-tree/HoonDongKang.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* [Problem]: [235] Lowest Common Ancestor of a Binary Search Tree
* (https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/description/)
*/

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;
}
}

function lowestCommonAncestor(
root: TreeNode | null,
p: TreeNode | null,
q: TreeNode | null
): TreeNode | null {
//시간복잡도 O(h)
//공간복잡도 O(h)
function recursiveFunc(
root: TreeNode | null,
p: TreeNode | null,
q: TreeNode | null
): TreeNode | null {
if (!p || !root || !q) return null;
if (p.val < root.val && q.val < root.val) {
return recursiveFunc(root.left, p, q);
}
if (root.val < p.val && root.val < q.val) {
return recursiveFunc(root.right, p, q);
}

return root;
}

//시간복잡도 O(h)
//공간복잡도 O(1)
function loopFunc(
root: TreeNode | null,
p: TreeNode | null,
q: TreeNode | null
): TreeNode | null {
if (!p || !q || !root) return null;

let node = root;

while (node) {
if (p.val < node.val && q.val < node.val) {
node = node?.left!;
} else if (p.val > node.val && q.val > node.val) {
node = node?.right!;
} else {
return node;
}
}

return null;
}
}
51 changes: 51 additions & 0 deletions meeting-rooms/HoonDongKang.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* [Problem]: [920] Meeting Rooms
* (https://www.lintcode.com/problem/920/)
*/

export class Interval {
start: number;
end: number;
constructor(start: number, end: number) {
this.start = start;
this.end = end;
}
}

export class Solution {
/**
* @param intervals: an array of meeting time intervals
* @return: if a person could attend all meetings
*/
canAttendMeetings(intervals: Interval[]): boolean {
//시간복잡도 O(n^2)
//공간복잡도 O(1)
function bruteForceFunc(intervals: Interval[]): boolean {
for (let i = 0; i < intervals.length; i++) {
for (let j = i + 1; j < intervals.length; j++) {
const first = intervals[i];
const second = intervals[j];
if (first.start < second.end && second.start < first.end) {
return false;
}
}
}

return true;
}

//시간복잡도 O(nlogn)
//공간복잡도 O(1)
function sortedFunc(intervals: Interval[]): boolean {
intervals.sort((a, b) => a.start - b.start);

for (let i = 0; i < intervals.length - 1; i++) {
if (intervals[i].end > intervals[i + 1].start) {
return false;
}
}

return true;
}
}
}