Skip to content

[alphaorderly] WEEK 13 Solutions - #2861

Open
alphaorderly wants to merge 2 commits into
DaleStudy:mainfrom
alphaorderly:week-13
Open

alphaorderly wants to merge 2 commits into
DaleStudy:mainfrom
alphaorderly:week-13

Conversation

@alphaorderly

@alphaorderly alphaorderly commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

답안 제출 문제

작성자 체크 리스트

  • Projects의 오른쪽 버튼(▼)을 눌러 확장한 뒤, Week를 현재 주차로 설정해주세요.
  • 문제를 모두 푸시면 프로젝트에서 StatusIn Review로 설정해주세요.
  • 코드 검토자 1분 이상으로부터 승인을 받으셨다면 PR을 병합해주세요.

검토자 체크 리스트

Important

본인 답안 제출 뿐만 아니라 다른 분 PR 하나 이상을 반드시 검토를 해주셔야 합니다!

  • 바로 이전에 올라온 PR에 본인을 코드 리뷰어로 추가해주세요.
  • 본인이 검토해야하는 PR의 답안 코드에 피드백을 주세요.
  • 토요일 전까지 PR을 병합할 수 있도록 승인해주세요.

Copy link
Copy Markdown
Contributor

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/alphaorderly.py
"""
시간 복잡도: O(LogN)
공간 복잡도: O(N)

최소 힙에는 스트림의 중간값보다 크거나 같은 값들이 저장됨
최대 힙에는 스트림의 중간값보다 작은 값들이 저장됨

두 힙의 경계에 위치한 값을 이용해 중간값을 구한다
"""
class MedianFinder:

    def __init__(self):
        self.min = []
        self.max = []

    def addNum(self, num: int) -> None:
        heapq.heappush_max(self.max, num)
        heapq.heappush(self.min, heapq.heappop_max(self.max))

        if len(self.min) > len(self.max):
            heapq.heappush_max(self.max, heapq.heappop(self.min))

    def findMedian(self) -> float:
        if len(self.max) == len(self.min):
            return (self.min[0] + self.max[0]) / 2
        else:
            return self.max[0]
  • 패턴: Two Pointers, Heap / Priority Queue
  • 설명: 데이터 스트림에서 중간값을 찾기 위해 두 개의 힙을 이용해 큰 값과 작은 값을 나누어 관리하는 패턴입니다. 힙을 이용한 크기 조정으로 중앙값을 빠르게 구하는 방식으로 Heap / Priority Queue 패턴에 속합니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(log n)
Space O(n)

피드백: 최대 힙과 최소 힙을 이용해 중앙값 경계를 유지하고 필요 시 재조정한다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

insert-interval/alphaorderly.py
"""
시간 복잡도: O(N)
공간 복잡도: O(N)
- 새로운 배열을 만들어 리턴하기 떄문이다.

기존 intervals 리스트에 새 interval을 삽입하여 겹치는 구간을 병합하는 코드입니다.
intervals는 이미 정렬되어 있다고 가정하며,
새로운 interval과의 겹침 여부를 판별하여 겹치면 병합하고, 그렇지 않으면 적절한 위치에 삽입합니다.
"""
class Solution:
    def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
        ans = []
        added = False

        for start, end in intervals:
            if added:
                ans.append([start, end])
                continue

            if end < newInterval[0]:
                ans.append([start, end])
            elif start > newInterval[1]:
                ans.append(newInterval)
                ans.append([start, end])
                added = True
            else:
                newInterval = [min(start, newInterval[0]), max(newInterval[1], end)]

        if not added:
            ans.append(newInterval)

        return ans
  • 패턴: Two Pointers, Greedy, Divide and Conquer
  • 설명: 정렬된 구간들을 순차적으로 탐색하며 새 구간과의 겹침 여부를 판단하고 필요 시 병합 또는 삽입하는 방식으로 해결합니다. 두 포인터처럼 시작/끝 값을 비교해 효율적으로 구간을 합치거나 위치를 정하는 패턴이 드러납니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space O(n)

피드백: 주어진 입력이 이미 정렬되어 있다는 가정하에 단일 순회로 병합/삽입을 수행한다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

kth-smallest-element-in-a-bst/alphaorderly.py
"""
시간 복잡도: O(N)
공간 복잡도: O(N)

이 코드는 이진 탐색 트리(BST)에서 k번째로 작은 값을 찾는 함수입니다.
중위 순회를 통해 노드를 오름차순으로 방문하여,
k번째 값을 찾는 방식으로 동작합니다.
"""
class Solution:
    def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
        stack = []
        index = 1

        while root:
            stack.append(root)
            root = root.left

        while stack:
            node = stack.pop()

            if index == k:
                return node.val
            index += 1

            if not node.right:
                continue

            right = node.right
            while right:
                stack.append(right)
                right = right.left

        return -1
  • 패턴: Two Pointers, Binary Search, Monotonic Stack, Hash Map / Hash Set, Depth-First Search, Inorder Traversal, Divide and Conquer, Greedy, Dynamic Programming, Backtracking, Trie, Bit Manipulation, Heap / Priority Queue, Union Find, BFS, Sliding Window, DFS, Monotonic Stack
  • 설명: 주요 아이디어는 이진 탐색 트리에서 중위 순회를 이용해 정렬된 순서를 얻고, 스택으로 구현된 비재귀 중위 순회로 k번째 작은 값을 찾는 패턴이다. 시간 복잡도는 O(N), 공간 복잡도는 O(N)으로 구현된다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space O(n)

피드백: 스택을 사용한 반복적 중위 순회로 순서를 따라간다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

@dalestudy

dalestudy Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

📊 alphaorderly 님의 학습 현황

이번 주 제출 문제

문제 난이도 유형 분석
find-median-from-data-stream Hard ✅ 의도한 유형
insert-interval Medium ✅ 의도한 유형
kth-smallest-element-in-a-bst Medium ✅ 의도한 유형
lowest-common-ancestor-of-a-binary-search-tree Medium ✅ 의도한 유형
meeting-rooms Easy ✅ 의도한 유형

누적 학습 요약

  • 풀이한 문제: 60 / 75개
  • 이번 주 유형 일치율: 100% (5문제 중 5문제 일치)

문제 풀이 현황

카테고리 진행도 완료
Array ■■■■■■■ 10 / 10 (Medium 7, Easy 3)
Linked List ■■■■■■■ 6 / 6 (Easy 3, Hard 1, Medium 2)
Dynamic Programming ■■■■■■□ 10 / 11 (Easy 1, Medium 9)
String ■■■■■■□ 9 / 10 (Medium 5, Hard 1, Easy 3)
Graph ■■■■■■□ 7 / 8 (Medium 7)
Binary ■■■■■■□ 4 / 5 (Easy 3, Medium 1)
Matrix ■■■■■□□ 3 / 4 (Medium 3)
Heap ■■■■■□□ 2 / 3 (Hard 1, Medium 1)
Tree ■■■■□□□ 8 / 14 (Hard 2, Medium 3, Easy 3)
Interval ■■■□□□□ 2 / 5 (Medium 2)

🤖 이 댓글은 GitHub App을 통해 자동으로 작성되었습니다.

🔢 API 사용량 (gpt-5-nano)
요청 입력 토큰 출력 토큰 합계 비용
1 2,082 243 2,325 $0.000201
2 2,082 210 2,292 $0.000188
합계 4,164 453 4,617 $0.000389

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

lowest-common-ancestor-of-a-binary-search-tree/alphaorderly.py
"""
시간 복잡도: O(N)
공간 복잡도: O(N)

BST에서 두 노드의 최소 공통 조상을 찾는 코드입니다.
두 노드의 값을 비교하여 최소 공통 조상을 찾는 방식으로 동작합니다.
"""
class Solution:
    def lowestCommonAncestor(
        self, root: "TreeNode", p: "TreeNode", q: "TreeNode"
    ) -> "TreeNode":
        if root == p or root == q:
            return root

        p_compare = root.val > p.val
        q_compare = root.val > q.val

        if p_compare != q_compare:
            return root
        elif p_compare and q_compare:
            return self.lowestCommonAncestor(root.left, p, q)
        else:
            return self.lowestCommonAncestor(root.right, p, q)
  • 패턴: Binary Search, Divide and Conquer
  • 설명: BST에서 두 노드의 위치 관계를 이용해 공통 조상을 찾는 방식으로, 분할과 재귀를 통해 문제를 해결합니다. BST 특성으로 경로를 한 방향으로 좁혀 가는 점이 포인트입니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space O(n)

피드백: 루트에서 값을 비교해 적절한 분기에서 재귀적으로 해결한다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

meeting-rooms/alphaorderly.py
"""
시간 복잡도: O(NLogN)
  - intervals 리스트를 정렬하기 때문입니다.
공간 복잡도: O(N)
  - 정렬 시 추가 메모리(새로운 배열)가 사용될 수 있습니다.

주어진 intervals(회의 시간표)들이 서로 겹치는지 확인하는 코드입니다.
intervals를 시작 시간 순으로 정렬한 뒤,
이전 회의의 종료 시간(final)과 현재 회의의 시작 시간(start)을 비교하여
회의가 겹치는 경우가 있는지 검사합니다.
"""
class Solution:
    def canAttendMeetings(self, intervals: List[List[int]]) -> bool:
        intervals.sort()
        final = -1

        for start, end in intervals:
            if start >= final:
                final = end
            else:
                return False

        return True
  • 패턴: Greedy, Two Pointers, Binary Search, Dynamic Programming, Divide and Conquer, Hash Map / Hash Set, Trie, Bit Manipulation, Union Find, Stack / Queue, BFS, DFS, Backtracking, Monotonic Stack, Heap / Priority Queue, Sliding Window, Fast & Slow Pointers, Dynamic Programming
  • 설명: 주 문제는 회의 시간대를 시작 시간 기준으로 정렬한 뒤, 현재 시작 시간이 직전에 종료 시간보다 크거나 같은지 검사하는 간단한 탐색 흐름으로 해를 구한다. 정렬으로 최적 해를 얻는 Greedy 패턴에 해당하며, 연속 구간 간의 중복 여부를 한 번의 순회로 판별한다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n log n)
Space O(n)

피드백: 정렬 비용으로 인해 전체 시간복잡도가 증가한다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Copy link
Copy Markdown
Contributor

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/alphaorderly.py
"""
시간 복잡도: O(LogN)
공간 복잡도: O(N)

최소 힙에는 스트림의 중간값보다 크거나 같은 값들이 저장됨
최대 힙에는 스트림의 중간값보다 작은 값들이 저장됨

두 힙의 경계에 위치한 값을 이용해 중간값을 구한다
"""
class MedianFinder:

    def __init__(self):
        self.min = []
        self.max = []

    def addNum(self, num: int) -> None:
        heapq.heappush_max(self.max, num)
        heapq.heappush(self.min, heapq.heappop_max(self.max))

        if len(self.min) > len(self.max):
            heapq.heappush_max(self.max, heapq.heappop(self.min))

    def findMedian(self) -> float:
        if len(self.max) == len(self.min):
            return (self.min[0] + self.max[0]) / 2
        else:
            return self.max[0]
  • 패턴: Two Pointers, Heap / Priority Queue
  • 설명: 데이터 스트림에서 중간값을 빠르게 구하기 위해 두 개의 힙(최대힙/최소힙)을 이용하는 패턴으로, 실시간 데이터에서 중앙값을 관리하는 데 사용됩니다.

📊 시간/공간 복잡도 분석

ℹ️ 이 파일에는 2가지 풀이가 포함되어 있어 각각 분석합니다.

풀이 1: MedianFinder.addNum — Time: O(log N) / Space: O(N)
복잡도
Time O(log N)
Space O(N)

피드백: 최솟값 큐와 최댓값 큐를 이용해 중간값을 빠르게 받아오도록 구현되어 있다.

개선 제안: 현재 구현은 간단하지만 Max Heap/Min Heap의 상호 변환 로직이 직관적이지 않으므로 명확한 주석과 함께 두 힙의 역할을 분리하면 가독성이 높아진다.

풀이 2: MeetingCanAttend.canAttendMeetings — Time: O(N log N) / Space: O(N)
복잡도
Time O(N log N)
Space O(N)

피드백: 정렬으로 인해 시간 복잡도는 O(N log N)이고, 순차 검사로 겹침 여부를 판정한다.

개선 제안: 최소 공간에서 동작하도록 정렬을 inplace로 유지하고, 시작/종료를 분리 리스트로 처리하는 방법도 고려해볼 수 있다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

meeting-rooms/alphaorderly.py
"""
시간 복잡도: O(NLogN)
  - intervals 리스트를 정렬하기 때문입니다.
공간 복잡도: O(N)
  - 정렬 시 추가 메모리(새로운 배열)가 사용될 수 있습니다.

주어진 intervals(회의 시간표)들이 서로 겹치는지 확인하는 코드입니다.
intervals를 시작 시간 순으로 정렬한 뒤,
이전 회의의 종료 시간(final)과 현재 회의의 시작 시간(start)을 비교하여
회의가 겹치는 경우가 있는지 검사합니다.
"""
class Solution:
    def canAttendMeetings(self, intervals: List[List[int]]) -> bool:
        intervals.sort()
        final = -1

        for start, end in intervals:
            if start >= final:
                final = end
            else:
                return False

        return True
  • 패턴: Greedy, Two Pointers, Dynamic Programming
  • 설명: 회의 일정 겹침 여부를 확인하기 위해 시작 시간을 기준으로 정렬한 뒤, 연속 구간의 종점과 다음 시작점을 비교하는 작은 탐색 흐름은 Greedy에 속하며, 정렬과 단순 비교로 문제를 해결합니다. 또한 시작/종료 시점을 한 번에 순회하는 점에서 Two Pointers의 연관성도 보이나 주로 Greedy 의사결정으로 해석합니다.

@DaleSeo
DaleSeo self-requested a review September 17, 2026 00:48

@DaleSeo DaleSeo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다. 화이팅!

self.max = []

def addNum(self, num: int) -> None:
heapq.heappush_max(self.max, num)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오, heappush_maxheappop_max는 처음 보네요. 덕분에 새로운 API 배워가네요 👍

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3.14에서 추가되었더라구요!!
원래는 불편함 때문에 MaxHeap 클래스를 따로 만들어 쓰는 편이였는데 너무 좋아요

Comment on lines +25 to +26
if not node.right:
continue

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아래 while right: 때문에 이 가드는 필요없지 않을까요?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞네요!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

2 participants