-
-
Notifications
You must be signed in to change notification settings - Fork 359
[yuseok89] WEEK 13 Solutions #2863
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
Changes from all commits
28866eb
46c37b9
e9a16d7
4a5585d
f42006c
d37475c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # TC (NlogN) | ||
| # SC (N) | ||
| class MedianFinder: | ||
|
|
||
| def __init__(self): | ||
| self.max_heap = [] | ||
| self.min_heap = [] | ||
|
|
||
| def addNum(self, num: int) -> None: | ||
| if len(self.min_heap) == 0 and len(self.max_heap) == 0: | ||
| heapq.heappush(self.min_heap, num) | ||
| elif len(self.max_heap) == 0: | ||
| mid = heapq.heappop(self.min_heap) | ||
| heapq.heappush(self.max_heap, -min(mid, num)) | ||
| heapq.heappush(self.min_heap, max(mid, num)) | ||
| elif len(self.max_heap) == len(self.min_heap): | ||
| mid1 = -self.max_heap[0] | ||
| mid2 = self.min_heap[0] | ||
|
|
||
| if num <= mid1: | ||
| heapq.heappush(self.max_heap, -num) | ||
| else: | ||
| heapq.heappush(self.min_heap, num) | ||
| else: | ||
| if len(self.max_heap) > len(self.min_heap): | ||
| mid = -heapq.heappop(self.max_heap) | ||
| else: | ||
| mid = heapq.heappop(self.min_heap) | ||
|
|
||
| heapq.heappush(self.max_heap, -min(mid, num)) | ||
| heapq.heappush(self.min_heap, max(mid, num)) | ||
|
|
||
| def findMedian(self) -> float: | ||
| if len(self.max_heap) == len(self.min_heap): | ||
| mid1 = -self.max_heap[0] | ||
| mid2 = self.min_heap[0] | ||
| return (mid1 + mid2) / 2.0 | ||
| else: | ||
| if len(self.max_heap) > len(self.min_heap): | ||
| return float(-self.max_heap[0]) | ||
| else: | ||
| return float(self.min_heap[0]) | ||
|
|
||
|
|
||
| # Your MedianFinder object will be instantiated and called as such: | ||
| # obj = MedianFinder() | ||
| # obj.addNum(num) | ||
| # param_2 = obj.findMedian() | ||
|
|
|
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. 🏷️ 알고리즘 패턴 분석insert-interval/yuseok89.py#TD: O(1)
#SC: O(2)
class Solution:
def insert(self, intervals: list[list[int]], newInterval: list[int]) -> list[list[int]]:
ans = []
is_processed = False
for interval in intervals:
if is_processed or interval[1] < newInterval[0]:
ans.append(interval)
elif newInterval[1] < interval[0]:
ans.append(newInterval)
ans.append(interval)
is_processed = True
else:
newInterval[0] = min(newInterval[0], interval[0])
newInterval[1] = max(newInterval[1], interval[1])
if not ans or ans[-1][1] < newInterval[0]:
ans.append(newInterval)
return ans
📊 시간/공간 복잡도 분석
피드백: 한 번의 순회로 중복 구간을 병합하며 결과 배열을 구성한다. 입력이 이미 정렬되어 있을 때 효율적이다. 개선 제안: 현재 구현이 적절해 보입니다.
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. 🏷️ 알고리즘 패턴 분석insert-interval/yuseok89.py#TC: O(1)
#SC: O(2)
class Solution:
def insert(self, intervals: list[list[int]], newInterval: list[int]) -> list[list[int]]:
ans = []
is_processed = False
for interval in intervals:
if is_processed or interval[1] < newInterval[0]:
ans.append(interval)
elif newInterval[1] < interval[0]:
ans.append(newInterval)
ans.append(interval)
is_processed = True
else:
newInterval[0] = min(newInterval[0], interval[0])
newInterval[1] = max(newInterval[1], interval[1])
if not ans or ans[-1][1] < newInterval[0]:
ans.append(newInterval)
return ans
📊 시간/공간 복잡도 분석
피드백: 정렬된 구간 리스트를 가정하고, 겹치지 않는 경우와 겹치는 경우를 나눠 처리한다. 새로운 구간과 기존 구간의 합치는 과정이 한 번의 순회로 끝난다. 개선 제안: 현재 구현이 적절해 보입니다.
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. 🏷️ 알고리즘 패턴 분석insert-interval/yuseok89.py#TC: O(N)
#SC: O(N)
class Solution:
def insert(self, intervals: list[list[int]], newInterval: list[int]) -> list[list[int]]:
ans = []
is_processed = False
for interval in intervals:
if is_processed or interval[1] < newInterval[0]:
ans.append(interval)
elif newInterval[1] < interval[0]:
ans.append(newInterval)
ans.append(interval)
is_processed = True
else:
newInterval[0] = min(newInterval[0], interval[0])
newInterval[1] = max(newInterval[1], interval[1])
if not ans or ans[-1][1] < newInterval[0]:
ans.append(newInterval)
return ans
📊 시간/공간 복잡도 분석
피드백: 모든 구간을 한 번의 순회로 처리하며 필요 시 새 구간과 기존 구간의 병합 결과를 업데이트합니다. 보조 리스트에 최종 결과를 저장합니다. 개선 제안: 현재 구현이 적절해 보입니다. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| #TC: O(N) | ||
| #SC: O(N) | ||
| class Solution: | ||
| def insert(self, intervals: list[list[int]], newInterval: list[int]) -> list[list[int]]: | ||
|
|
||
| ans = [] | ||
| is_processed = False | ||
|
|
||
| for interval in intervals: | ||
| if is_processed or interval[1] < newInterval[0]: | ||
| ans.append(interval) | ||
| elif newInterval[1] < interval[0]: | ||
| ans.append(newInterval) | ||
| ans.append(interval) | ||
| is_processed = True | ||
| else: | ||
| newInterval[0] = min(newInterval[0], interval[0]) | ||
| newInterval[1] = max(newInterval[1], interval[1]) | ||
|
|
||
| if not ans or ans[-1][1] < newInterval[0]: | ||
| ans.append(newInterval) | ||
|
|
||
| return ans | ||
|
|
|
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. 🏷️ 알고리즘 패턴 분석kth-smallest-element-in-a-bst/yuseok89.py# TC: O(N)
# SC: O(1)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def kthSmallest(self, root: TreeNode | None, k: int) -> int:
ans = 0
def rec(node: TreeNode | None) -> None:
nonlocal k, ans
if node is None or k <= 0:
return
rec(node.left)
k -= 1
if k == 0:
ans = node.val
return
rec(node.right)
rec(root)
return ans
📊 시간/공간 복잡도 분석
피드백: Left-Root-Right 순회로 정확히 k번째 노드를 찾도록 구현했다. 재귀 깊이에 따라 공간 복잡도가 좌우된다. 개선 제안: 재귀 대신 반복 방문으로 스택 사용을 명확히 관리하면 공간 예측이 쉬워진다.
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. 🏷️ 알고리즘 패턴 분석kth-smallest-element-in-a-bst/yuseok89.py# TC: O(N)
# SC: O(H)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def kthSmallest(self, root: TreeNode | None, k: int) -> int:
ans = 0
def rec(node: TreeNode | None) -> None:
nonlocal k, ans
if node is None or k <= 0:
return
rec(node.left)
k -= 1
if k == 0:
ans = node.val
return
rec(node.right)
rec(root)
return ans
📊 시간/공간 복잡도 분석
피드백: 왼쪽 자식부터 방문하고 방문한 순서를 카운트하여 k번째 노드를 찾습니다. 재귀 깊이는 트리의 높이와 같습니다. 개선 제안: 현재 구현이 적절해 보입니다. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # TC: O(N) | ||
| # SC: O(H) | ||
| # Definition for a binary tree node. | ||
| # class TreeNode: | ||
| # def __init__(self, val=0, left=None, right=None): | ||
| # self.val = val | ||
| # self.left = left | ||
| # self.right = right | ||
| class Solution: | ||
| def kthSmallest(self, root: TreeNode | None, k: int) -> int: | ||
|
|
||
| ans = 0 | ||
|
|
||
| def rec(node: TreeNode | None) -> None: | ||
| nonlocal k, ans | ||
|
|
||
| if node is None or k <= 0: | ||
| return | ||
|
|
||
| rec(node.left) | ||
|
|
||
| k -= 1 | ||
| if k == 0: | ||
| ans = node.val | ||
| return | ||
|
|
||
| rec(node.right) | ||
|
|
||
| rec(root) | ||
|
|
||
| return ans | ||
|
|
|
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. 🏷️ 알고리즘 패턴 분석lowest-common-ancestor-of-a-binary-search-tree/yuseok89.py# TC: O(H)
# SC: O(1)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if root.val < p.val and root.val < q.val:
return self.lowestCommonAncestor(root.right, p, q)
elif root.val > p.val and root.val > q.val:
return self.lowestCommonAncestor(root.left, p, q)
else:
return root
📊 시간/공간 복잡도 분석
피드백: BST의 특성을 이용해 루트와 노드 값의 대소 비교만으로 LCA를 찾는 간단한 재귀 풀이이다. 개선 제안: 현재 구현이 적절해 보입니다.
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. 🏷️ 알고리즘 패턴 분석lowest-common-ancestor-of-a-binary-search-tree/yuseok89.py# TC: O(H)
# SC: O(H)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if root.val < p.val and root.val < q.val:
return self.lowestCommonAncestor(root.right, p, q)
elif root.val > p.val and root.val > q.val:
return self.lowestCommonAncestor(root.left, p, q)
else:
return root
📊 시간/공간 복잡도 분석
피드백: BST의 성질: 두 노드의 값이 서로 다른 방향으로 배열되면 그 노드가 LCA이다. 재귀적으로 최적 경로로 내려간다. 개선 제안: 재귀 깊이가 커질 경우 스택 오버플로를 주의하고, 반복 방식으로 구현해도 된다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # TC: O(H) | ||
| # SC: O(H) | ||
| # Definition for a binary tree node. | ||
| # class TreeNode: | ||
| # def __init__(self, x): | ||
| # self.val = x | ||
| # self.left = None | ||
| # self.right = None | ||
|
|
||
| class Solution: | ||
| def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode': | ||
| if root.val < p.val and root.val < q.val: | ||
| return self.lowestCommonAncestor(root.right, p, q) | ||
| elif root.val > p.val and root.val > q.val: | ||
| return self.lowestCommonAncestor(root.left, p, q) | ||
| else: | ||
| return root | ||
|
|
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.
🏷️ 알고리즘 패턴 분석
find-median-from-data-stream/yuseok89.py
📊 시간/공간 복잡도 분석
피드백: 두 개의 힙을 유지하며 삽입 시 균형을 유지해 중앙값을 구한다. 각 연산은 힙 원소 재배열로 로그 시간 복잡도를 가진다.
개선 제안: 현재 구현이 적절해 보입니다.