Skip to content

[Tessa1217] Week14 Solutions #1640

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 14 commits into from
Jul 2, 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
87 changes: 87 additions & 0 deletions binary-tree-level-order-traversal/Tessa1217.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
* 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 {

// DFS 풀이
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
dfs(root, 0, result);
return result;
}

private void dfs(TreeNode node, int depth, List<List<Integer>> result) {
if (node == null) {
return;
}

// 깊이만큼의 리스트가 없으면 새 리스트 추가하기
if (depth == result.size()) {
result.add(new ArrayList<>());
}

result.get(depth).add(node.val);

dfs(node.left, depth + 1, result);
dfs(node.right, depth + 1, result);


}

// BFS로 풀이
// O(n)
// public List<List<Integer>> levelOrder(TreeNode root) {
//
// List<List<Integer>> result = new ArrayList<>();
//
// if (root == null) {
// return result;
// }
//
// Queue<TreeNode> queue = new LinkedList<>();
// queue.offer(root);
//
// while (!queue.isEmpty()) {
// int nodeCnt = queue.size();
// List<Integer> currentLevelNodes = new ArrayList<>();
//
// for (int i = 0; i < nodeCnt; i++) {
// TreeNode current = queue.poll();
// currentLevelNodes.add(current.val);
//
// if (current.left != null) {
// queue.offer(current.left);
// }
//
// if (current.right != null) {
// queue.offer(current.right);
// }
//
// }
//
// result.add(currentLevelNodes);
//
// }
//
// return result;
//
// }
}

14 changes: 14 additions & 0 deletions counting-bits/Tessa1217.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Solution {

// 시간복잡도: O(n)
public int[] countBits(int n) {
int[] bitsArray = new int[n + 1];
for (int i = 1; i <= n; i++) {
// Shift 연산자 사용
// i&1 => 마지막 비트가 0인지 1인지 확인
bitsArray[i] = bitsArray[i >> 1] + (i & 1);
}
return bitsArray;
}
}

46 changes: 46 additions & 0 deletions find-median-from-data-stream/Tessa1217.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import java.util.PriorityQueue;

class MedianFinder {

// 작은 수 범위 저장하는 힙
private PriorityQueue<Integer> smallHeap;

// 큰 수 범위 저장하는 힙
private PriorityQueue<Integer> 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();
*/

45 changes: 45 additions & 0 deletions house-robber-ii/Tessa1217.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
class Solution {

// DP
public int rob(int[] nums) {
int n = nums.length;

if (n == 0) {
return 0;
}

if (n == 1) {
return nums[0];
}

int notRobbingLast = robHouses(nums, 0, n - 2);
int notRobbingFirst = robHouses(nums, 1, n - 1);

return Math.max(notRobbingLast, notRobbingFirst);
}

private int robHouses(int[] nums, int start, int end) {

int length = end - start + 1;

if (length == 0) {
return 0;
}

if (length == 1) {
return nums[start];
}

int[] dp = new int[length];

dp[0] = nums[start];
dp[1] = Math.max(nums[start], nums[start + 1]);

for (int i = 2; i < length; i++) {
dp[i] = Math.max(dp[i - 2] + nums[start + i], dp[i - 1]);
}

return dp[length - 1];
}
}

39 changes: 39 additions & 0 deletions insert-interval/Tessa1217.java
Original file line number Diff line number Diff line change
@@ -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<int[]> 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]);
}
}

51 changes: 51 additions & 0 deletions kth-smallest-element-in-a-bst/Tessa1217.java
Original file line number Diff line number Diff line change
@@ -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);

}

}

33 changes: 33 additions & 0 deletions lowest-common-ancestor-of-a-binary-search-tree/Tessa1217.java
Original file line number Diff line number Diff line change
@@ -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;
}

}
}

55 changes: 55 additions & 0 deletions meeting-rooms-ii/Tessa1217.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import java.util.List;
import java.util.PriorityQueue;

/**
* 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: the minimum number of conference rooms required
*/
// 시간복잡도: O(n log n)
public int minMeetingRooms(List<Interval> intervals) {

if (intervals == null || intervals.isEmpty()) {
return 0;
}

// 주어진 시간 인터벌 리스트를 시작 시간 기준으로 정렬
intervals.sort((i1, i2) -> i1.start - i2.start);

// PriorityQueue 선언: 시간 interval의 end time 기준
PriorityQueue<Interval> meetingRooms = new PriorityQueue<>((i1, i2) -> i1.end - i2.end);

for (Interval interval : intervals) {

// 최초 meeting room
if (meetingRooms.isEmpty()) {
meetingRooms.offer(interval);
continue;
}

Interval meeting = meetingRooms.peek();
// (0, 8), (8, 10) is not conflict at 8
if (meeting.end <= interval.start) {
// 앞의 회의 종료되었으므로 회의실 재사용
meetingRooms.poll();
}
// 새 회의실 추가
meetingRooms.offer(interval);
}

return meetingRooms.size();

}
}

Loading