diff --git a/non-overlapping-intervals/imsosleepy.java b/non-overlapping-intervals/imsosleepy.java new file mode 100644 index 000000000..61fb9d109 --- /dev/null +++ b/non-overlapping-intervals/imsosleepy.java @@ -0,0 +1,22 @@ +// 정렬을 하지 않으면 O(N^2)이 확정인 문제 +// 정렬을 해서 O(NlogN)으로 해결 +class Solution { + public int eraseOverlapIntervals(int[][] intervals) { + if (intervals.length == 0) return 0; + + Arrays.sort(intervals, (a, b) -> a[1] - b[1]); + + int count = 0; + int prevEnd = intervals[0][1]; + + for (int i = 1; i < intervals.length; i++) { + if (intervals[i][0] < prevEnd) { + count++; + } else { + prevEnd = intervals[i][1]; + } + } + return count; + } +} + diff --git a/number-of-connected-components-in-an-undirected-graph/imsosleepy.java b/number-of-connected-components-in-an-undirected-graph/imsosleepy.java new file mode 100644 index 000000000..9aaa368f1 --- /dev/null +++ b/number-of-connected-components-in-an-undirected-graph/imsosleepy.java @@ -0,0 +1,34 @@ +// 그래프에서 연결된 컴포넌트 개수를 구하는 문제 +// 인접 리스트로 변환, DFS로 연결을 확인한다 +// 그래프 변환 → O(E) (간선 수), DFS/BFS 탐색 → O(V + E) (노드 + 간선) +class Solution { + public int countComponents(int n, int[][] edges) { + List> graph = new ArrayList<>(); + for (int i = 0; i < n; i++) { + graph.add(new ArrayList<>()); + } + + for (int[] edge : edges) { + graph.get(edge[0]).add(edge[1]); + graph.get(edge[1]).add(edge[0]); + } + + boolean[] visited = new boolean[n]; + int count = 0; + for (int i = 0; i < n; i++) { + if (!visited[i]) { + dfs(i, graph, visited); + count++; + } + } + return count; + } + + private void dfs(int node, List> graph, boolean[] visited) { + if (visited[node]) return; + visited[node] = true; + for (int neighbor : graph.get(node)) { + dfs(neighbor, graph, visited); + } + } +} diff --git a/remove-nth-node-from-end-of-list/imsosleepy.java b/remove-nth-node-from-end-of-list/imsosleepy.java new file mode 100644 index 000000000..c0f153e2e --- /dev/null +++ b/remove-nth-node-from-end-of-list/imsosleepy.java @@ -0,0 +1,25 @@ + // 노드 전체를 한번만 탐색하게 만들었음 따라서 O(N) + // 투포인터 방식으로 하나를 N+1 위치로 보내서 N번째 노드를 제거한 후 oneStep과 연결한다. + // oneStep은 삭제할 노드 바로 직전 노드 + // 사이즈가 1일 때를 범용적으로 처리하기 위해 머리를 굴렸음... +class Solution { + public ListNode removeNthFromEnd(ListNode head, int n) { + ListNode defaultNode = new ListNode(0); + defaultNode.next = head; + ListNode twoStep = defaultNode; + ListNode oneStep = defaultNode; + + for (int i = 0; i <= n; i++) { + twoStep = twoStep.next; + } + + while (twoStep != null) { + twoStep = twoStep.next; + oneStep = oneStep.next; + } + + oneStep.next = oneStep.next.next; + + return defaultNode.next; + } +} diff --git a/same-tree/imsosleepy.java b/same-tree/imsosleepy.java new file mode 100644 index 000000000..881237e15 --- /dev/null +++ b/same-tree/imsosleepy.java @@ -0,0 +1,10 @@ +class Solution { + public boolean isSameTree(TreeNode p, TreeNode q) { + // 끝까지 내려왔으면 같다. + if (p == null && q == null) return true; + // 끝까지 내려왔는데, 값이 다르다. + if (p == null || q == null || p.val != q.val) return false; + // 양쪽 다 탐색 + return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); + } +} diff --git a/serialize-and-deserialize-binary-tree/imsosleepy.java b/serialize-and-deserialize-binary-tree/imsosleepy.java new file mode 100644 index 000000000..63f50efd0 --- /dev/null +++ b/serialize-and-deserialize-binary-tree/imsosleepy.java @@ -0,0 +1,88 @@ +// 문제 해석 부터 안되서 GPT에게 도움을 요청 +// Serialize (직렬화): 트리를 문자열로 변환하는 과정. +// Deserialize (역직렬화): 문자열을 다시 트리로 변환하는 과정. +// 트리를 저장하고 복원할 수 있는 형식이라면 어떤 방법이든 가능. +// 🔹 해결 방법 +// 우리는 BFS(너비 우선 탐색)와 큐(Queue)를 활용한 방식을 사용할 거야. +// 이 방식을 선택한 이유는: + +// 트리의 구조를 유지하면서도 직렬화하기 쉽다. +// 문자열이 순차적으로 만들어져 역직렬화할 때도 다시 순차적으로 트리를 복원하기 편하다. +public class Codec { + + // 직렬화 (Serialize) + public String serialize(TreeNode root) { + if (root == null) return "null"; // 빈 트리 처리 + + StringBuilder sb = new StringBuilder(); + Queue queue = new LinkedList<>(); + queue.offer(root); + + while (!queue.isEmpty()) { + TreeNode node = queue.poll(); + + if (node == null) { + sb.append("null,"); + } else { + sb.append(node.val).append(","); + queue.offer(node.left); + queue.offer(node.right); + } + } + return sb.toString(); + } + + // 역직렬화 (Deserialize) + public TreeNode deserialize(String data) { + if (data.equals("null")) return null; // 빈 트리 처리 + + String[] values = data.split(","); + TreeNode root = new TreeNode(Integer.parseInt(values[0])); + Queue queue = new LinkedList<>(); + queue.offer(root); + + int i = 1; + while (!queue.isEmpty()) { + TreeNode node = queue.poll(); + + if (!values[i].equals("null")) { + node.left = new TreeNode(Integer.parseInt(values[i])); + queue.offer(node.left); + } + i++; + + if (!values[i].equals("null")) { + node.right = new TreeNode(Integer.parseInt(values[i])); + queue.offer(node.right); + } + i++; + } + return root; + } +} + +// 트리는 대부분 DFS로 해결했어서 비슷한 방식을 생각했으나 구현 실패 +// GPT에게 이어서 작업을 했고 O(N)의 시간복잡도를 얻음. 그러나 위의 BFS보다 속도가 느림 +class Codec { + // 🔹 DFS 기반 직렬화 (Serialize) + public String serialize(TreeNode root) { + if (root == null) return "null"; + return root.val + "," + serialize(root.left) + "," + serialize(root.right); + } + + // 🔹 DFS 기반 역직렬화 (Deserialize) + public TreeNode deserialize(String data) { + Queue nodes = new LinkedList<>(Arrays.asList(data.split(","))); + return buildTree(nodes); + } + + private TreeNode buildTree(Queue nodes) { + String val = nodes.poll(); + if (val.equals("null")) return null; + + TreeNode node = new TreeNode(Integer.parseInt(val)); + node.left = buildTree(nodes); + node.right = buildTree(nodes); + return node; + } +}