Skip to content

[parkhojeong] WEEK 10 Solutions - #2844

Merged
dalestudy[bot] merged 4 commits into
DaleStudy:mainfrom
parkhojeong:week10
Aug 30, 2026
Merged

[parkhojeong] WEEK 10 Solutions#2844
dalestudy[bot] merged 4 commits into
DaleStudy:mainfrom
parkhojeong:week10

Conversation

@parkhojeong

@parkhojeong parkhojeong commented Aug 29, 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.

🏷️ 알고리즘 패턴 분석

course-schedule/parkhojeong.py
class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        course_to_precourses: dict[str, set[int]] = {}
        precourse_to_courses: dict[str, set[int]] = {}

        for course, pre_course in prerequisites:
            if course not in course_to_precourses:
                course_to_precourses[course] = set()
            course_to_precourses[course].add(pre_course)

            if pre_course not in precourse_to_courses:
                precourse_to_courses[pre_course] = set()
            precourse_to_courses[pre_course].add(course)

        stack = []
        for course in range(numCourses):
            if course not in course_to_precourses:
                stack.append(course)

        while stack:
            pre_course = stack.pop()
            if pre_course in precourse_to_courses:
                for course in precourse_to_courses[pre_course]:
                    course_to_precourses[course].remove(pre_course)

                    if len(course_to_precourses[course]) == 0:
                        stack.append(course)

        for course in course_to_precourses:
            if len(course_to_precourses[course]) != 0:
                return False

        return True
  • 패턴: Topological Sort, Hash Map / Hash Set
  • 설명: Prerequisite 그래프에서 위상정렬(Topological Sort)을 사용해 순환 여부를 판단한다. 각 강의의 선행 과목을 관리하고, 진입 차수가 0인 노드를 제거하며 사이클 존재 여부를 검사한다. 해시 맵과 집합으로 그래프 정보를 유지한다.

📊 시간/공간 복잡도 분석

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

풀이 1: Solution.canFinish — Time: O(V + E) / Space: O(V + E)
복잡도
Time O(V + E)
Space O(V + E)

피드백: 모든 간선 정보를 양방향 맵으로 구성하고, 진입 차수가 0인 노드부터 차례로 제거하며 사이클 여부를 확인한다.

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

풀이 2: Solution.invertTree — Time: O(n) / Space: O(h)
복잡도
Time O(n)
Space O(h)

피드백: 각 노드를 한 번씩 방문하고 스택/재귀를 통해 자식들을 처리한다.

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

풀이 3: Solution.canJump — Time: O(n) / Space: O(1)
복잡도
Time O(n)
Space O(1)

피드백: 선형 스캔으로 가능성을 확인하므로 최악의 경우에도 한 번의 패스가 필요하다.

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

풀이 4: Solution.mergeKLists — Time: O(k n) / Space: O(1)
복잡도
Time O(k n)
Space O(1)

피드백: 각 단계에서 최소 값을 찾는 선형 스캔으로 비효율적이다. 히드드 리스트나 우선순위 큐를 활용하면 개선됩니다.

개선 제안: 고려해볼 만한 대안: 힙을 이용한 병합으로 시간 복잡도를 O(n log k)로 낮출 수 있습니다.

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

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.

🏷️ 알고리즘 패턴 분석

invert-binary-tree/parkhojeong.py
# 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 invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if not root:
            return root

        def dfs(node: Optional[TreeNode]):
            node.right, node.left = node.left, node.right

            if node.left:
                dfs(node.left)
            if node.right:
                dfs(node.right)

        dfs(root)

        return root
  • 패턴: Depth-First Search, Binary Search
  • 설명: 코드에서 이진 트리를 재귀적으로 방문하며 노드의 좌우를 교환하는 DFS 방식의 트리 순회 패턴이 사용됩니다. 트리의 각 노드에 대해 좌우를 스왑하고 재귀적으로 자식 노드로 내려가는 구조입니다.

@dalestudy

dalestudy Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

📊 parkhojeong 님의 학습 현황

이번 주 제출 문제

문제 난이도 유형 분석
course-schedule Medium ✅ 의도한 유형
invert-binary-tree Easy ✅ 의도한 유형
jump-game Medium ⚠️ 유형 불일치
merge-k-sorted-lists Hard ⚠️ 유형 불일치

누적 학습 요약

  • 풀이한 문제: 41 / 75개
  • 이번 주 유형 일치율: 50% (4문제 중 2문제 일치)

문제 풀이 현황

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

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

🔢 API 사용량 (gpt-5-nano)
요청 입력 토큰 출력 토큰 합계 비용
1 1,612 257 1,869 $0.000183

Comment thread jump-game/parkhojeong.py

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.

🏷️ 알고리즘 패턴 분석

jump-game/parkhojeong.py
class Solution:
    def canJump(self, nums: List[int]) -> bool:
        max_jump = 0
        i = 0
        arr = [0] * len(nums)
        while i <= max_jump:
            num = nums[i]
            for j in range(min(num + i, len(nums) - 1), i - 1, -1):
                if arr[j] == 1:
                    break
                arr[j] = 1
                max_jump = max(max_jump, j)

            i += 1

        return len(nums) - 1 == max_jump
  • 패턴: Greedy, Dynamic Programming
  • 설명: 배열의 최대 도달 위치를 추적하며 현재 위치에서 가능한 여러 점에 도달 여부를 기록하는 방식으로 최댓값 갱신. 도달 여부를 배열으로 저장하고, 한 위치에서 다른 위치로 확장하는 점에서 DP/그리디의 혼합 패턴으로 해석 가능.

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.

🏷️ 알고리즘 패턴 분석

merge-k-sorted-lists/parkhojeong.py
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
        if len(lists) == 0:
            return

        if sum([1 if node is None else 0 for node in lists]) == len(lists):
            return

        def find_min():
            idx = -1
            min_val = sys.maxsize
            i = 0
            for l in lists:
                if l is not None and min_val > l.val:
                    min_val = l.val
                    idx = i
                i += 1

            return idx

        idx = find_min()
        node = lists[idx]
        head = node
        lists[idx] = lists[idx].next
        while node:
            idx = find_min()
            if idx == -1:
                break
            node.next = lists[idx]
            node = node.next
            lists[idx] = lists[idx].next

        return head
  • 패턴: Two Pointers, Heap / Priority Queue
  • 설명: 리스트의 각 노드를 차례대로 비교해 가장 작은 값을 선택하여 연결하는 방식으로, 여러 리스트의 노드를 하나의 정렬된 리스트로 병합한다. 매 단계에서 최소 원소를 찾는 탐색과 연결 포인터를 이동시키는 패턴이 두 포인터/힙 대기열의 아이디어와 유사하다.

@github-actions github-actions Bot added the py label Aug 29, 2026

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.

특정 배열에서 동적으로 최소값을 찾는 자료구조가 있죠!
지금은 3000ms정도 시간이 소요되는데 이건 "출제자가 배우길 의도한 정답" 과는 좀 거리가 있을 것 같습니다.
시간복잡도를 최적화 해 보시는 것을 시도해 보시면 좋겠네요!

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.

최적화 하시면 5~11ms정도로 가능하십니다!

Comment thread jump-game/parkhojeong.py

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.

해당 풀이는 Amortized O(N)에 가깝긴 하지만 개인적으로 불필요한 부분 ( 가장 멀리 갈수 있는 거리만 확인하면 되는데 모든 거리에 대해 갈수 있는지 여부를 확인함 ) 이 저장되어 있다는게 맘에 걸리네요
실제로 최적화시 시간은 4배가량 빨라질수 있고 공간 복잡도 또한 추가공간 O(1)에 가능하십니다.

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.

제 생각에 DFS 함수를 개별 구현하지 않고 invertTree 메서드 자체에서 바로 재귀하는것이 더 낫지 않을까? 싶습니다.

@dalestudy dalestudy Bot left a comment

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.

현재 주차가 종료되어 자동으로 승인되었습니다. PR을 병합해주세요!

@dalestudy
dalestudy Bot merged commit fa11753 into DaleStudy:main Aug 30, 2026
3 checks passed
@github-project-automation github-project-automation Bot moved this from In Review to Completed in 리트코드 스터디 8기 Aug 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Completed

Development

Successfully merging this pull request may close these issues.

2 participants