-
-
Notifications
You must be signed in to change notification settings - Fork 357
[okyungjin] WEEK 14 Solutions #2866
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
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. 확실히 레벨오더는 큐를 쓰는게 가장 깔끔한거 같긴 해요
Contributor
Author
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. 오홍 체감을 위해 다른 방법으로도 풀어봐야겠네요 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # 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 |
|
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. 🏷️ 알고리즘 패턴 분석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
📊 시간/공간 복잡도 분석
피드백: 앞선 값들을 이용해 현재 값을 계산하는 방식으로 연속적으로 채워 나간다. n까지의 모든 값을 한 번씩 계산하므로 시간은 선형이고, dp 배열이 필요하므로 공간도 선형이다. 개선 제안: 현재 구현이 적절해 보입니다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # 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) | ||
|
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. 반환값은 복잡도에 포함하지 않은것이지요?
Contributor
Author
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.
@yuseok89 네 맞습니다! |
||
| """ | ||
| 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 | ||
|
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. 🏷️ 알고리즘 패턴 분석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)
📊 시간/공간 복잡도 분석
피드백: 두 구간 문제를 독립적으로 해결한 뒤 최대를 취하는 방식으로, 선형 스캔과 상수 공간으로 해결한다. 개선 제안: 현재 구현이 적절해 보입니다.
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. 진짜 함수로 일반화 하는게 맞았나 싶기도 하네요 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # 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) |
|
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. 🏷️ 알고리즘 패턴 분석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
📊 시간/공간 복잡도 분석
피드백: 정렬과 우선순위 큐를 이용해 현재 열려 있는 방의 수를 관리한다. 각 회의마다 끝나는 시간을 갱신해 필요한 방 수를 결정한다. 개선 제안: 현재 구현이 적절해 보입니다.
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. 오 ㅋㅋㅋ 저랑 거의 완벽하게 동일한 풀이를 사용하셨네요
Contributor
Author
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. 고민하다가 도저히 모르겠어서 클로드의 도움을 살짝 받았습니다 ㅎㅎ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| # 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 |
|
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. 🏷️ 알고리즘 패턴 분석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
📊 시간/공간 복잡도 분석
피드백: 종료 시간 정렬 후 순차 탐색으로 충돌 여부를 판정한다. 상수 공간으로 해결 가능하다. 개선 제안: 현재 구현이 적절해 보입니다.
Contributor
Author
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. @DaleStudy 유형 불일치야? 모범답안 알려줘
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. 질문 핵심: 타입/일관성 불일치가 있는지와 모범답안 여부. 요점
모범답안에 대한 제안
간단 요약
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # 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 |
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.
🏷️ 알고리즘 패턴 분석
binary-tree-level-order-traversal/okyungjin.py
📊 시간/공간 복잡도 분석
피드백: 큐를 이용해 각 노드를 레벨별로 묶어 결과를 만든다. 모든 노드를 한 번씩 방문하므로 시간은 선형이고, 최악의 경우 같은 수의 노드를 담으므로 공간도 선형이다.
개선 제안: 현재 구현이 적절해 보입니다.