Skip to content

[okyungjin] WEEK 14 Solutions - #2866

Open
okyungjin wants to merge 5 commits into
DaleStudy:mainfrom
okyungjin:main
Open

okyungjin wants to merge 5 commits into
DaleStudy:mainfrom
okyungjin:main

Conversation

@okyungjin

@okyungjin okyungjin commented Sep 21, 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.

🏷️ 알고리즘 패턴 분석

binary-tree-level-order-traversal/okyungjin.py
# 102. Binary Tree Level Order Traversal
# https://leetcode.com/problems/binary-tree-level-order-traversal/

"""
문제:
    - 이진 트리의 root가 주어질 때, 노드 값을 레벨 순서(왼쪽에서 오른쪽, 위에서 아래)로 묶어서 반환한다
    - 결과는 레벨별 값 리스트의 리스트 (예: [[3], [9, 20], [15, 7]])
    - 0 <= 노드 수 <= 2000

복잡도:
    n: 노드의 개수
    Time: O(n)
    Space: O(n)
"""
# 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 levelOrder(self, root: TreeNode | None) -> list[list[int]]:
        if not root:
            return []

        ans = []
        q = deque([(0, root)])
        while q:
            level, node = q.popleft()
            if len(ans) == level:
                ans.append([])
            ans[level].append(node.val)
            if node.left:
                q.append((level + 1, node.left))
            if node.right:
                q.append((level + 1, node.right))

        return ans
  • 패턴: Breadth-First Search, Queue/Deque usage
  • 설명: 노드를 레벨별로 차례대로 방문하여 각 레벨의 값을 모으는 방식으로, 큐를 사용한 너비 우선 탐색(BFS) 패턴에 해당한다. 레벨 구분은 현재 레벨 깊이를 경로로 추적하는 방식으로 구현되어 있다.

📊 시간/공간 복잡도 분석

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

피드백: 큐를 이용해 각 노드를 레벨별로 묶어 결과를 만든다. 모든 노드를 한 번씩 방문하므로 시간은 선형이고, 최악의 경우 같은 수의 노드를 담으므로 공간도 선형이다.

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

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

@dalestudy

dalestudy Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

📊 okyungjin 님의 학습 현황

이번 주 제출 문제

문제 난이도 유형 분석
binary-tree-level-order-traversal Medium ✅ 의도한 유형
counting-bits Easy ✅ 의도한 유형
house-robber-ii Medium ✅ 의도한 유형
meeting-rooms-ii Medium ✅ 의도한 유형
meeting-rooms Easy ⚠️ 유형 불일치

누적 학습 요약

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

문제 풀이 현황

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

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

🔢 API 사용량 (gpt-5-nano)
요청 입력 토큰 출력 토큰 합계 비용
1 2,402 212 2,614 $0.000205

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.

🏷️ 알고리즘 패턴 분석

counting-bits/okyungjin.py
# 338. Counting Bits
# https://leetcode.com/problems/counting-bits/

"""
문제:
    - 정수 n이 주어질 때, 0부터 n까지 각 i에 대해 i의 이진 표현에 포함된 1의 개수를 구한다
    - 결과는 길이 n + 1인 배열 ans로 반환한다 (ans[i] = i의 1의 개수)
    - 0 <= n <= 10^5

복잡도:
    n: 입력 정수 n
    Time: O(n)
    Space: O(1)
"""
class Solution:
    def countBits(self, n: int) -> List[int]:
        dp = [0]
        offset = 1

        for num in range(1, n + 1):
            if num == offset * 2:
                offset = num
            dp.append(dp[num - offset] + 1)

        return dp
  • 패턴: Dynamic Programming, Divide and Conquer
  • 설명: 숫자 i의 이진 표현에서 1의 개수를 i-1의 패턴을 활용해 계산하는 점화로, 이전 결과를 이용해 새로운 값을 빠르게 구한다. 또한 부분 문제를 합쳐 전체 결과를 만들어 내는 DP 특성을 보인다.

📊 시간/공간 복잡도 분석

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

피드백: 앞선 값들을 이용해 현재 값을 계산하는 방식으로 연속적으로 채워 나간다. n까지의 모든 값을 한 번씩 계산하므로 시간은 선형이고, 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.

🏷️ 알고리즘 패턴 분석

house-robber-ii/okyungjin.py
# 213. House Robber II
# https://leetcode.com/problems/house-robber-ii/

"""
문제:
    - 집들이 원형으로 배치되어 있고, 각 집에는 돈이 들어 있다.
    - 인접한 두 집은 같은 날 털 수 없다.
    - 첫 집과 마지막 집도 인접한 것으로 본다.
    - 털 수 있는 최대 금액을 구한다.

복잡도:
    n: `nums`의 길이
    Time: O(n)
    Space: O(1)
"""
class Solution:
    def rob(self, nums: List[int]) -> int:
        n = len(nums)
        if n == 1:
            return nums[0]

        def steel(start, end):
            prev2, prev1 = 0, 0
            for i in range(start, end):
                cur = max(prev2 + nums[i], prev1)
                prev2, prev1 = prev1, cur
            return prev1

        s1 = steel(0, n - 1)
        s2 = steel(1, n)
        return max(s1, s2)
  • 패턴: Dynamic Programming, Two Pointers
  • 설명: 큐브의 DP 아이디어로 부분 문제의 최적해를 누적해 구하는 방식이며, 원형 배열에서 부분 구간의 최적해를 비교하기 위해 선형 스캔과 상태 누적을 활용한다. 또한 각 위치의 선택 여부를 두 이전 상태와 비교해 최댓값을 갱신한다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space 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.

🏷️ 알고리즘 패턴 분석

meeting-rooms-ii/okyungjin.py
# 253. Meeting Rooms II
# https://www.lintcode.com/problem/919/

"""
문제:
    - 회의 시간 구간 `[start, end)` 목록이 주어진다. (start < end)
    - 모든 회의를 진행하는 데 필요한 최소 회의실 개수를 구한다.
    - 한 회의가 끝나는 시각에 다른 회의가 시작하는 것은 충돌이 아니다.

복잡도:
    n: `intervals`의 길이
    Time: O(n log n)
    Space: O(n)
"""
import heapq

"""
Definition of Interval:
class Interval(object):
    def __init__(self, start, end):
        self.start = start
        self.end = end
"""
class Solution:
    def min_meeting_rooms(self, intervals: List[Interval]) -> int:
        pq = []
        intervals.sort(key=lambda x: x.start)

        for cur in intervals:
            if pq:
                earliest_end = pq[0]  # 열린 방들 중 가장 빨리 끝나는 시각
                if cur.start >= earliest_end:
                    heapq.heappop(pq)
            heapq.heappush(pq, cur.end)

        return len(pq)

# print(Solution().min_meeting_rooms([Interval(0, 30), Interval(5, 10), Interval(15, 20)]))  # 2
# print(Solution().min_meeting_rooms([Interval(0, 5), Interval(5, 10), Interval(10, 15)]))  # 1
# print(Solution().min_meeting_rooms([Interval(1, 10), Interval(2, 7), Interval(3, 9), Interval(8, 12)]))  # 3
  • 패턴: Heap / Priority Queue, Greedy, Two Pointers
  • 설명: 회의실 최소 개수를 구하는 방식으로 끝나는 시간들을 우선순위 큐로 관리하고, 시작 시각과 가장 먼저 끝나는 회의의 종료 시점을 비교하여 재사용 여부를 판단한다. 정렬과 힙 구조를 활용한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.

🏷️ 알고리즘 패턴 분석

meeting-rooms/okyungjin.py
# 252. Meeting Rooms
# https://www.lintcode.com/problem/920/

"""
문제:
    - 회의 시간 구간 `[start, end)` 목록이 주어진다. (start < end)
    - 한 사람이 모든 회의에 참석할 수 있는지 True/False로 반환한다.
    - 한 회의가 끝나는 시각에 다른 회의가 시작하는 것은 충돌이 아니다.

복잡도:
    n: `intervals`의 길이
    Time: O(n log n)
    Space: O(n)
"""

"""
Definition of Interval:
class Interval(object):
    def __init__(self, start, end):
        self.start = start
        self.end = end
"""
class Solution:
    def can_attend_meetings(self, intervals: List[Interval]) -> bool:
        intervals.sort(key=lambda x: x.end)

        last_end = 0
        for interval in intervals:
            if interval.start < last_end:
                return False
            last_end = interval.end
        return True
  • 패턴: Greedy, Binary Search, Sorting
  • 설명: 간격을 끝시간으로 정렬한 뒤, 이전 회의 종료 시간과 현재 시작 시간을 비교하는 방식으로 충돌 여부를 판단한다. 이는 최적해를 찾는 탐욕적 패턴과 정렬을 이용한 전처리의 조합이다.

📊 시간/공간 복잡도 분석

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

피드백: 종료 시간 정렬 후 순차 탐색으로 충돌 여부를 판정한다. 상수 공간으로 해결 가능하다.

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

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

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.

@DaleStudy 유형 불일치야? 모범답안 알려줘

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.

질문 핵심: 타입/일관성 불일치가 있는지와 모범답안 여부.

요점

  • 그래프/레벨 순서, 카운팅 비트 등 여러 문제에 대해 타입 힌트가 섞여 있습니다.
  • 문제: 일부 파일에서 List, deque, Interval 등 타입이 보이지 않는 경우가 있습니다. 예를 들어,
    • counting-bits: List[int]를 사용하지만 List가 import되어 있지 않음. 또한 dp를 리스트로 반환하는데 사용된 주석과 실제 코드의 타입 힌트 불일치 가능성(입력 n에 대한 타입) 존재.
    • meeting-rooms/okyungjin.py 등에서 List[Interval]를 사용하지만 Interval 정의나 import가 주석 처리되어 있어 타입 힌트 불일치.
    • level-order 등에서 TreeNode | None 같은 파이썬 3.10+ 구문을 사용하지만 필요한 타입 정의나 import가 보이지 않음.

모범답안에 대한 제안

  • 공통 포맷 유지: 각 파일 맨 위에 필요한 import를 명확히 추가
    • from typing import List, Optional
    • 또는 Python 3.10+으로 동일하게 사용 시 from typing import List
  • 함수 시그니처에서 일관된 타입 표기
    • 예: def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
  • 필요한 TreeNode/Interval 정의를 코드 내에 명시적으로 포함하거나, 주석으로 정의를 확실히 할 것
  • 모범 예시(간략):
    • counting-bits: import List, 구현에서 List[int] 반환
    • meeting-rooms: Interval 정의를 코드 상단에 포함, 리스트 정렬 시 Interval 타입 사용
    • binary-tree-level-order-traversal: from collections import deque, Optional, List

간단 요약

  • 네 파일 중 일부는 타입 힌트와 필요 정의(import/Interval/TreeNode 등)가 누락되어 타입 불일치 문제가 있습니다.
  • 권장: 각 파일에 필요한 타입 임포트와 정의를 명확히 추가하고, 시그니처를 일관되게 맞춰 모범답안 형식으로 통일하세요.

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.

확실히 레벨오더는 큐를 쓰는게 가장 깔끔한거 같긴 해요

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.

진짜 함수로 일반화 하는게 맞았나 싶기도 하네요
깔끔한 코드 좋아요!

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.

오 ㅋㅋㅋ 저랑 거의 완벽하게 동일한 풀이를 사용하셨네요
신기합니다!

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

Labels

Projects

Status: Solving

Development

Successfully merging this pull request may close these issues.

2 participants