diff --git a/find-median-from-data-stream/Tessa1217.java b/find-median-from-data-stream/Tessa1217.java new file mode 100644 index 000000000..ff717faf6 --- /dev/null +++ b/find-median-from-data-stream/Tessa1217.java @@ -0,0 +1,46 @@ +import java.util.PriorityQueue; + +class MedianFinder { + + // 작은 수 범위 저장하는 힙 + private PriorityQueue smallHeap; + + // 큰 수 범위 저장하는 힙 + private PriorityQueue largeHeap; + + public MedianFinder() { + smallHeap = new PriorityQueue<>((a, b) -> b - a); + largeHeap = new PriorityQueue<> ((a, b) -> a - b); + } + + public void addNum(int num) { + // 작은 수 범위에 삽입 + smallHeap.offer(num); + // 작은 수 범위에서 최댓값을 뽑아 큰 수 범위로 이동 + largeHeap.offer(smallHeap.poll()); + + // 만약 작은 수 범위의 개수가 큰 수 범위보다 작다면 + if (smallHeap.size() < largeHeap.size()) { + // 큰 수 범위에서 최솟값을 뽑아 작은 수 범위로 이동 + smallHeap.offer(largeHeap.poll()); + } + } + + public double findMedian() { + // 짝수 개일 경우 + if (smallHeap.size() == largeHeap.size()) { + // 작은 수 범위 힙의 최댓값 + 큰 수 범위 힙의 최솟값의 평균 + return (smallHeap.peek() + largeHeap.peek()) / 2.0; + } + // 작은 수 범위 힙의 최댓값 + return smallHeap.peek(); + } +} + +/** + * Your MedianFinder object will be instantiated and called as such: + * MedianFinder obj = new MedianFinder(); + * obj.addNum(num); + * double param_2 = obj.findMedian(); + */ + diff --git a/insert-interval/Tessa1217.java b/insert-interval/Tessa1217.java new file mode 100644 index 000000000..8e14916ab --- /dev/null +++ b/insert-interval/Tessa1217.java @@ -0,0 +1,39 @@ +import java.util.ArrayList; +import java.util.List; + +class Solution { + + // 시간, 공간복잡도: O(n) + public int[][] insert(int[][] intervals, int[] newInterval) { + + // 병합된 interval 담는 list + List modifyIntervals = new ArrayList<>(); + + int idx = 0; + + // 병합 이전 구간 + while (idx < intervals.length && intervals[idx][1] < newInterval[0]) { + modifyIntervals.add(intervals[idx]); + idx++; + } + + // 병합이 필요한 구간 (newInterval과 겹치는 구간) + while (idx < intervals.length && intervals[idx][0] <= newInterval[1]) { + newInterval[0] = Math.min(intervals[idx][0], newInterval[0]); + newInterval[1] = Math.max(intervals[idx][1], newInterval[1]); + idx++; + } + + // 최종 병합된 새로운 interval add + modifyIntervals.add(newInterval); + + // 병합 이후 구간 + while (idx < intervals.length) { + modifyIntervals.add(intervals[idx]); + idx++; + } + + return modifyIntervals.toArray(new int[modifyIntervals.size()][2]); + } +} + diff --git a/kth-smallest-element-in-a-bst/Tessa1217.java b/kth-smallest-element-in-a-bst/Tessa1217.java new file mode 100644 index 000000000..452fd995a --- /dev/null +++ b/kth-smallest-element-in-a-bst/Tessa1217.java @@ -0,0 +1,51 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + + private int count = 0; + + private int kthSmallValue = 0; + + // 시간복잡도: O(k) (불균형 상태의 이진 트리일 경우 O(n)) + public int kthSmallest(TreeNode root, int k) { + orderSearch(root, k); + return kthSmallValue; + } + + // In Order Search + private void orderSearch(TreeNode node, int k) { + + if (node == null) { + return; + } + + // HINT => utilize the property of a BST => 좌측 리프 노드부터 탐색 + orderSearch(node.left, k); + + count++; + + if (count == k) { + kthSmallValue = node.val; + return; + } + + // search right side + orderSearch(node.right, k); + + } + +} + diff --git a/lowest-common-ancestor-of-a-binary-search-tree/Tessa1217.java b/lowest-common-ancestor-of-a-binary-search-tree/Tessa1217.java new file mode 100644 index 000000000..cc5d2dfb2 --- /dev/null +++ b/lowest-common-ancestor-of-a-binary-search-tree/Tessa1217.java @@ -0,0 +1,33 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +class Solution { + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + + if (root == null || root == p || root == q) { + return root; + } + + // 재귀로 좌측과 우측 탐색 + TreeNode left = lowestCommonAncestor(root.left, p, q); + + TreeNode right = lowestCommonAncestor(root.right, p, q); + + // 좌우 둘 다 null이 아니라면: 현재 root를 조상으로 하는 서브 트리에서 p와 q를 발견했음을 의미하므로 root가 공통 조상 + if (left != null && right != null) { + return root; + } else if (left != null) { + return left; + } else { + return right; + } + + } +} + diff --git a/meeting-rooms/Tessa1217.java b/meeting-rooms/Tessa1217.java new file mode 100644 index 000000000..3ad8cf994 --- /dev/null +++ b/meeting-rooms/Tessa1217.java @@ -0,0 +1,42 @@ +import java.util.Collections; +import java.util.List; + +/** + * Definition of Interval: + * public class Interval { + * int start, end; + * Interval(int start, int end) { + * this.start = start; + * this.end = end; + * } + * } + */ + +public class Solution { + /** + * @param intervals: an array of meeting time intervals + * @return: if a person could attend all meetings + */ + + // 시간복잡도: O(n log n) - 정렬, 공간복잡도: O(1) + public boolean canAttendMeetings(List intervals) { + // Write your code here + + if (intervals == null || intervals.isEmpty()) return true; + + Collections.sort(intervals, (i1, i2) -> i1.start - i2.start); + + Interval previous = intervals.get(0); + + for (int i = 1; i < intervals.size(); i++) { + Interval current = intervals.get(i); + if (previous.end > current.start) { + return false; + } + previous = current; + } + + return true; + } +} +