-
-
Notifications
You must be signed in to change notification settings - Fork 194
[hi-rachel] Week 14 Solutions #1639
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
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
8940ac5
counting-bits solution (py)
hi-rachel 02e02e5
counting-bits solution (ts)
hi-rachel 070dab3
binary-tree-level-order-traversal solution (py)
hi-rachel 762b9cc
binary-tree-level-order-traversal solution (ts)
hi-rachel e4555f4
meeting-rooms-ii solution (py)
hi-rachel 5774844
house-robber-ii solution (py)
hi-rachel 50a7da3
house-robber-ii solution (ts)
hi-rachel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
""" | ||
주어진 이진 트리를 위에서 아래로, 왼쪽에서 오른쪽으로 레벨 단위로 순회하여 | ||
각 레벨에 있는 노드들의 값을 리턴하는 문제 | ||
|
||
TC: O(N), 모든 노드를 한 번씩 방문 | ||
SC: O(N), 큐와 결과 리스트에 최대 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 | ||
|
||
from collections import deque | ||
from typing import Optional, List | ||
|
||
class Solution: | ||
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||
if not root: | ||
return [] | ||
|
||
output = [] | ||
queue = deque([root]) | ||
|
||
while queue: | ||
# 현재 레벨에 있는 모든 노드들의 값을 리스트에 담기 | ||
level = [node.val for node in queue] | ||
output.append(level) | ||
|
||
# 현재 레벨에 있는 모든 노드 탐색 | ||
for _ in range(len(queue)): | ||
node = queue.popleft() | ||
if node.left: | ||
queue.append(node.left) | ||
if node.right: | ||
queue.append(node.right) | ||
|
||
return output |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/** | ||
* python의 len(queue)는 반복 시작 전에 계산된 값, 즉 고정된 횟수만큼 반복 | ||
* JS의 queue.length는 반복마다 실시간으로 다시 계산하므로 고정 사이즈 size 변수 사용 | ||
*/ | ||
|
||
/** | ||
* Definition for a binary tree node. | ||
*/ | ||
class TreeNode { | ||
val: number; | ||
left: TreeNode | null; | ||
right: TreeNode | null; | ||
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { | ||
this.val = val === undefined ? 0 : val; | ||
this.left = left === undefined ? null : left; | ||
this.right = right === undefined ? null : right; | ||
} | ||
} | ||
|
||
function levelOrder(root: TreeNode | null): number[][] { | ||
if (!root) return []; | ||
|
||
const queue: TreeNode[] = [root]; | ||
const output: number[][] = []; | ||
|
||
while (queue.length > 0) { | ||
const level: number[] = []; | ||
for (let node of queue) { | ||
level.push(node.val); | ||
} | ||
output.push(level); | ||
const size = queue.length; | ||
|
||
for (let i = 0; i < size; i++) { | ||
const node = queue.shift(); | ||
if (node && node.left) { | ||
queue.push(node.left); | ||
} | ||
if (node && node.right) { | ||
queue.push(node.right); | ||
} | ||
} | ||
} | ||
return output; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
""" | ||
정수 n이 주어졌을 때, 0부터 n까지의 모든 수에 대해 각 수를 이진수로 표현했을 때 1의 개수를 구하는 문제 | ||
|
||
TC: O(N log N), 모든 수 순환 + 이진수 변환 과정 (log i) | ||
SC: O(N) | ||
""" | ||
|
||
from typing import List | ||
|
||
# 처음 풀이 | ||
class Solution: | ||
def countBits(self, n: int) -> List[int]: | ||
def countOne(num): | ||
cnt = 0 | ||
while True: | ||
rest = num % 2 | ||
if rest == 1: | ||
cnt += 1 | ||
num //= 2 | ||
if num <= 1: | ||
if num == 1: | ||
cnt += 1 | ||
break | ||
return cnt | ||
|
||
result = [] | ||
for i in range(0, n + 1): | ||
result.append(countOne(i)) | ||
|
||
return result | ||
|
||
""" | ||
DP 풀이 - 시간 복잡도 개선 | ||
|
||
bits[i] = bits[i >> 1] + (i &) | ||
i >> 1 은 i를 오른쪽으로 1비트 이동 -> i를 2로 나눈 값 | ||
i & 1 은 i의 마지막 1비트가 1인지 확인, 짝수면 0, 홀수면 1 | ||
i의 1의 개수 = i를 2로 나눈 수의 1의 개수 + 마지막 비트가 1인지 여부 | ||
|
||
TC: O(N) | ||
SC: O(N) | ||
""" | ||
|
||
class Solution: | ||
def countBits(self, n: int) -> List[int]: | ||
dp = [0] * (n + 1) | ||
for i in range(1, n + 1): | ||
dp[i] = dp[i >> 1] + (i & 1) | ||
return dp |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
function countBits(n: number): number[] { | ||
const result: number[] = new Array(n + 1).fill(0); | ||
|
||
for (let i = 0; i <= n; i++) { | ||
result[i] = result[i >> 1] + (i & 1); | ||
} | ||
return result; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
""" | ||
이웃집은 못텀, 주어진 nums list 집은 원형으로 이어져 있음 (맨 처음 <- > 맨 마지막 이웃) | ||
가장 많은 돈을 가지고 있는 집을 최대한으로 턴 총 금액을 반환 | ||
|
||
1. 첫 집을 포함하고, 마지막 집을 제외하는 경우 nums[:-1] | ||
2. 첫 집을 제외하고, 마지막 집을 포함하는 경우 nums[1:] | ||
|
||
TC: O(N), | ||
SC: O(N) | ||
""" | ||
|
||
from typing import List | ||
|
||
class Solution: | ||
def rob(self, nums: List[int]) -> int: | ||
if len(nums) == 0: | ||
return 0 | ||
if len(nums) == 1: | ||
return nums[0] | ||
if len(nums) == 2: | ||
return max(nums) | ||
|
||
def rob_linear(houses: List[int]) -> int: | ||
if len(houses) == 1: | ||
return houses[0] | ||
|
||
dp = [0] * len(houses) | ||
dp[0] = houses[0] | ||
dp[1] = max(houses[0], houses[1]) | ||
for i in range(2, len(houses)): | ||
dp[i] = max(dp[i - 1], houses[i] + dp[i - 2]) | ||
return dp[-1] | ||
|
||
case1 = rob_linear(nums[:-1]) | ||
case2 = rob_linear(nums[1:]) | ||
|
||
return max(case1, case2) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
function rob(nums: number[]): number { | ||
if (nums.length === 1) return nums[0]; | ||
if (nums.length === 2) return Math.max(nums[0], nums[1]); | ||
|
||
function rob_linear(nums: number[]): number { | ||
const size = nums.length; | ||
const dp = new Array(size).fill(0); | ||
dp[0] = nums[0]; | ||
dp[1] = Math.max(nums[0], nums[1]); | ||
for (let i = 2; i < size; i++) { | ||
dp[i] = Math.max(nums[i] + dp[i - 2], dp[i - 1]); | ||
} | ||
return dp[dp.length - 1]; | ||
} | ||
|
||
return Math.max( | ||
rob_linear(nums.slice(0, nums.length - 1)), | ||
rob_linear(nums.slice(1)) | ||
); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
""" | ||
https://neetcode.io/problems/meeting-schedule-ii | ||
|
||
주어지는 회의 시간 리스트 intervals = [[s₁, e₁], [s₂, e₂], ...] (각 si < ei)에 대해, | ||
동시에 진행되는 회의의 최대 개수, 즉 필요한 최소 회의실 개수를 계산하는 문제 | ||
|
||
TC: O(N log N), 회의 시간 정렬 O(N log N) | ||
SC: O(N), 배열 사용 | ||
""" | ||
|
||
#Definition of Interval: | ||
class Interval(object): | ||
def __init__(self, start, end): | ||
self.start = start | ||
self.end = end | ||
|
||
from typing import List | ||
|
||
class Solution: | ||
def minMeetingRooms(self, intervals: List[List[int]]) -> int: | ||
if not intervals: | ||
return 0 | ||
|
||
# 회의 시작 시간과 종료 시간을 저장하는 배열 | ||
start_times = [interval.start for interval in intervals] | ||
end_times = [interval.end for interval in intervals] | ||
|
||
# 시작 시간과 종료 시간을 정렬 | ||
start_times.sort() | ||
end_times.sort() | ||
|
||
# 회의실 개수 초기화 | ||
rooms = 0 | ||
end_index = 0 | ||
|
||
# 각 회의 시작 시간을 순회하며 회의실 개수 계산 | ||
for start in start_times: | ||
# 현재 회의 시작 시간이 이전 회의 종료 시간보다 크거나 같으면 회의실 개수 줄이기 | ||
if start >= end_times[end_index]: | ||
rooms -= 1 | ||
end_index += 1 | ||
rooms += 1 | ||
|
||
return rooms | ||
|
||
|
||
|
||
""" | ||
힙 풀이 | ||
|
||
TC: O(N log N), 회의 시간 정렬 O(N log N) | ||
SC: O(N), 최악의 경우 모든 회의가 겹침 | ||
""" | ||
|
||
import heapq | ||
|
||
class Solution: | ||
def minMeetingRooms(self, intervals: List[Interval]) -> int: | ||
if not intervals: | ||
return 0 | ||
|
||
intervals.sort(key=lambda x: x.start) | ||
|
||
heap = [] | ||
|
||
for interval in intervals: | ||
start = interval.start | ||
end = interval.end | ||
|
||
# 현재 회의의 시작 시간 >= 가장 빨리 끝나는 회의의 종료 시간이라면 | ||
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. 최소 힙 이용, 항상 가장 빨리 끝나는 회의가 heap[0]에 위치
heap 정리: https://bitbetter.vercel.app/blog/datastructures/heap |
||
# 그 회의실은 다시 사용할 수 있으므로 heap에서 제거 (pop) | ||
if heap and heap[0] <= start: | ||
heapq.heappop(heap) | ||
|
||
# 새 회의의 종료 시간을 힙에 추가 | ||
heapq.heappush(heap, end) | ||
|
||
# 힙에 남아 있는 종료 시간 수 = 동시에 진행 중인 회의 수 = 필요한 최소 회의실 수 | ||
return len(heap) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
비트 연산자를 활용할수도 있군요.. 자주 안써봐서 생소했는데 하나 배워갑니다!