-
-
Notifications
You must be signed in to change notification settings - Fork 336
[juhui-jeong] WEEK 13 Solutions #2616
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
풀이 1:
|
| 복잡도 | |
|---|---|
| Time | O(n log n) |
| Space | O(1) |
피드백: intervals 배열을 정렬한 후, 겹치는 구간을 찾으며 최소 제거 횟수를 계산한다. 정렬이 시간 복잡도를 결정하며, 이후 반복문은 O(n)이다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 2: Solution.eraseOverlapIntervals — Time: O(n log n) / Space: O(1)
| 복잡도 | |
|---|---|
| Time | O(n log n) |
| Space | O(1) |
피드백: 끝나는 시간 기준으로 정렬하여 겹치는 구간을 최소화한다. 정렬 후 반복문은 O(n)이며, 전체 시간 복잡도는 정렬에 의해 결정된다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 3: Solution.eraseOverlapIntervals — Time: ✅ O(n log n) → O(n log n) / Space: ❌ O(n) → O(1)
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(n log n) | O(n log n) | ✅ |
| Space | O(n) | O(1) | ❌ |
피드백: 배열을 정렬한 후, 이전 종료 시간과 비교하여 겹침 여부를 판단한다. 정렬이 시간 복잡도를 지배하며, 반복문은 O(n)이다.
개선 제안: 현재 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,51 +1,79 @@ | ||
| /* | ||
| * 끝나는 시간 오름차순 정렬 | ||
| */ | ||
| 처음 풀이 | ||
| 시작 시간 기준 정렬 | ||
| class Solution { | ||
| public int eraseOverlapIntervals(int[][] intervals) { | ||
| Arrays.sort(intervals, (a,b) -> Integer.compare(a[1], b[1])); | ||
| Arrays.sort(intervals, (a,b) -> { | ||
| if (a[0] != b[0]) return Integer.compare(a[0], b[0]); | ||
| return Integer.compare(a[1], b[1]); | ||
| }); | ||
|
|
||
| int removeCntResult = 0; | ||
| int end = intervals[0][1]; | ||
| int[] cur = intervals[0]; | ||
|
|
||
| for (int i = 1; i< intervals.length; i++) { | ||
| if (intervals[i][0] < end) { | ||
| int [] next = intervals[i]; | ||
|
|
||
| if (cur[1] > next[0]) { | ||
| removeCntResult += 1; | ||
| if (next[1] < cur[1]) { | ||
| cur = next; | ||
| } | ||
| } else { | ||
| end = intervals[i][1]; | ||
| cur = next; | ||
| } | ||
| } | ||
| return removeCntResult; | ||
| } | ||
| } | ||
| */ | ||
|
|
||
|
|
||
| /* | ||
| 처음 풀이 | ||
| 시작 시간 기준 정렬 | ||
| * 끝나는 시간 오름차순 정렬 | ||
|
|
||
| class Solution { | ||
| public int eraseOverlapIntervals(int[][] intervals) { | ||
| Arrays.sort(intervals, (a,b) -> { | ||
| if (a[0] != b[0]) return Integer.compare(a[0], b[0]); | ||
| return Integer.compare(a[1], b[1]); | ||
| }); | ||
| Arrays.sort(intervals, (a,b) -> Integer.compare(a[1], b[1])); | ||
|
|
||
| int removeCntResult = 0; | ||
| int[] cur = intervals[0]; | ||
| int end = intervals[0][1]; | ||
|
|
||
| for (int i = 1; i< intervals.length; i++) { | ||
| int [] next = intervals[i]; | ||
|
|
||
| if (cur[1] > next[0]) { | ||
| if (intervals[i][0] < end) { | ||
| removeCntResult += 1; | ||
| if (next[1] < cur[1]) { | ||
| cur = next; | ||
| } | ||
| } else { | ||
| cur = next; | ||
| end = intervals[i][1]; | ||
| } | ||
| } | ||
| return removeCntResult; | ||
| } | ||
| } | ||
| */ | ||
|
|
||
| /** | ||
| * 시간 복잡도: O(n log n) | ||
| * 공간 복잡도: O(n) | ||
| */ | ||
| class Solution { | ||
| public int eraseOverlapIntervals(int[][] intervals) { | ||
| Arrays.sort(intervals, (a,b) -> a[0] - b[0]); | ||
| int count = 0; | ||
| int prevEnd = intervals[0][1]; | ||
|
|
||
| for (int i = 1; i < intervals.length; i++) { | ||
| int curStart = intervals[i][0]; | ||
| int curEnd = intervals[i][1]; | ||
|
|
||
| if (prevEnd <= curStart) { | ||
| // 안겹치는 경우(변경 없이 다음 배열로) | ||
| prevEnd = curEnd; | ||
| } else { | ||
| // 겹치는 경우 | ||
| count++; | ||
| prevEnd = Math.min(prevEnd, curEnd); | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| } |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
풀이 1:
|
| 복잡도 | |
|---|---|
| Time | O(n) |
| Space | O(1) |
피드백: 더미 노드를 활용하여 fast와 slow 포인터를 n만큼 차이 나게 이동시킨 후, 동시에 이동하며 제거 위치를 찾는다. 시간은 리스트 길이 n에 비례하며, 공간은 상수이다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 2: Solution.removeNthFromEnd — Time: ✅ O(n) → O(n) / Space: ✅ O(1) → O(1)
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(n) | O(n) | ✅ |
| Space | O(1) | O(1) | ✅ |
피드백: 리스트 전체 길이를 먼저 계산한 후, 제거할 위치를 찾아서 노드를 연결한다. 두 번의 순회로 해결하며, 시간은 리스트 길이 n에 비례한다.
개선 제안: 현재 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
풀이 1:
|
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(n) | O(n) | ✅ |
| Space | O(h) | O(h) | ✅ |
피드백: 두 트리의 노드 값을 비교하며 재귀적으로 좌우 서브트리를 탐색한다. 모든 노드를 방문하므로 시간 복잡도는 O(n), 재귀 호출 스택은 트리 높이 h에 비례한다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 2: Solution.isSameTree — Time: ✅ O(n) → O(n) / Space: ✅ O(n) → O(n)
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(n) | O(n) | ✅ |
| Space | O(n) | O(n) | ✅ |
피드백: 두 트리를 레벨별로 큐를 이용해 비교한다. 모든 노드를 방문하므로 시간은 O(n), 큐의 크기는 최악의 경우 전체 노드 수에 비례한다.
개선 제안: 현재 구현이 적절해 보입니다.
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
풀이 1:
|
| 복잡도 | |
|---|---|
| Time | O(n) |
| Space | O(n) |
피드백: 트리의 모든 노드를 순회하며 문자열로 변환한다. 노드 수 n에 비례하는 시간과 공간이 소요된다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 2: Codec.deserialize — Time: O(n) / Space: O(n)
| 복잡도 | |
|---|---|
| Time | O(n) |
| Space | O(n) |
피드백: 문자열을 배열로 분할 후 재귀적으로 노드를 복원한다. 노드 수 n에 비례하는 시간과 공간이 소요된다.
개선 제안: 현재 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
|
|
||
| public class Codec { | ||
| private int index; | ||
|
|
||
| // Encodes a tree to a single string.(직렬화) | ||
| public String serialize(TreeNode root) { | ||
| StringBuilder sb = new StringBuilder(); | ||
| dfsSerialize(root, sb); | ||
| return sb.toString(); | ||
| } | ||
|
|
||
| private void dfsSerialize(TreeNode node, StringBuilder sb) { | ||
| if (node == null) { | ||
| sb.append("null").append(","); | ||
| return; | ||
| } | ||
| sb.append(node.val).append(","); | ||
|
|
||
| dfsSerialize(node.left, sb); | ||
| dfsSerialize(node.right, sb); | ||
| } | ||
|
|
||
| // Decodes your encoded data to tree.(역직렬화) | ||
| public TreeNode deserialize(String data) { | ||
| String[] arr = data.split(","); | ||
| index = 0; | ||
| return dfsDeserialize(arr); | ||
| } | ||
|
|
||
| private TreeNode dfsDeserialize(String[] arr) { | ||
| String value = arr[index++]; | ||
|
|
||
| if (value.equals("null")) { | ||
| return null; | ||
| } | ||
|
|
||
| TreeNode node = new TreeNode(Integer.parseInt(value)); | ||
|
|
||
| node.left = dfsDeserialize(arr); | ||
| node.right = dfsDeserialize(arr); | ||
| return node; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
풀이 1:
Solution.lowestCommonAncestor— Time: O(h) / Space: O(1)피드백: 트리의 높이 h에 비례하는 반복문을 통해, p와 q의 값에 따라 좌우로 내려가며 최적의 공통 조상을 찾는다. 최악의 경우 트리의 높이만큼 탐색하므로 O(h) 시간과 O(1) 공간이 소요된다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 2:
Solution.lowestCommonAncestor— Time: O(h) / Space: O(h)피드백: 재귀 호출을 통해 트리의 높이만큼 호출 스택이 쌓이므로, 시간은 트리 높이 h에 비례하고 공간은 O(h)이다. p와 q의 값에 따라 좌우로 내려가며 최적의 공통 조상을 찾는다.
개선 제안: 현재 구현이 적절해 보입니다.