diff --git a/binary-tree-level-order-traversal/radiantchoi.py b/binary-tree-level-order-traversal/radiantchoi.py new file mode 100644 index 0000000000..8ce0a21cb1 --- /dev/null +++ b/binary-tree-level-order-traversal/radiantchoi.py @@ -0,0 +1,42 @@ +from collections import deque, defaultdict +from typing import Optional, List + +# 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: Optional[TreeNode]) -> List[List[int]]: + # 앞으로의 코드는 root가 있다는 것을 전제로 수행 + # 또한 root가 None이라면 기록해서 돌려 줄 값도 없기 때문에 early return + if not root: + return [] + + # depth별 노드를 기록할 defaultdict + nodes = defaultdict(list) + # bfs 탐색에 사용될 queue + queue = deque() + + # root는 존재함이 보장되므로, 반복문의 시동을 위해 root node를 queue에 추가 + # 이 때 깊이 정보도 함께 묶어서 tuple로 추가 + queue.append((root, 0)) + + while queue: + current = queue.popleft() + + # 현재 노드의 값 기록 + nodes[current[1]].append(current[0].val) + + # 현재 노드의 왼쪽 자식 노드가 존재한다면, 해당 노드와 깊이 정보를 함께 queue에 추가 + if current[0].left: + queue.append((current[0].left, current[1] + 1)) + + # 현재 노드의 오른쪽 자식 노드가 존재한다면, 해당 노드와 깊이 정보를 함께 queue에 추가 + if current[0].right: + queue.append((current[0].right, current[1] + 1)) + + # 깊이 순서대로 dict에 추가되었으므로, values()를 사용하여 리스트로 변환하여 반환 + return list(nodes.values()) diff --git a/counting-bits/radiantchoi.ts b/counting-bits/radiantchoi.ts new file mode 100644 index 0000000000..a335f422d9 --- /dev/null +++ b/counting-bits/radiantchoi.ts @@ -0,0 +1,12 @@ +function countBits(n: number): number[] { + let base = 1; + let result = [0]; + + while (base <= n) { + const numberOfBits = Array.from(base.toString(2)).filter(num => num === "1").length; + result.push(numberOfBits); + base += 1; + } + + return result; +}; diff --git a/house-robber-ii/radiantchoi.ts b/house-robber-ii/radiantchoi.ts new file mode 100644 index 0000000000..cb6de28974 --- /dev/null +++ b/house-robber-ii/radiantchoi.ts @@ -0,0 +1,27 @@ +function rob(nums: number[]): number { + if (nums.length < 3) { + return Math.max(...nums); + } + + // House Robber II의 핵심: 원형으로 연결된 집들을, 연결되지 않은 두 부분으로 나눈다 + let first = nums.slice(0, nums.length - 1); + let second = nums.slice(1, nums.length); + + // House Robber 점화식의 첫 번째 항: 첫 번째 집과 두 번째 집을, 둘 중 더 큰 값으로 미리 동기화해 둔다 + first[1] = Math.max(first[0], first[1]); + second[1] = Math.max(second[0], second[1]); + + // 배열 길이 조건을 만족할 경우, House Robber 1번 문제처럼 점화식을 사용하여 각 배열의 값을 업데이트 + if (nums.length > 2) { + for (let i = 2; i < nums.length - 1; i++) { + first[i] = Math.max(first[i] + first[i - 2], first[i - 1]) + second[i] = Math.max(second[i] + second[i - 2], second[i - 1]) + } + } + + // 두 결과 중 더 큰 것을 반환 + let firstResult = Math.max(...first); + let secondResult = Math.max(...second); + + return Math.max(firstResult, secondResult); +}; diff --git a/lowest-common-ancestor-of-a-binary-search-tree/radiantchoi.swift b/lowest-common-ancestor-of-a-binary-search-tree/radiantchoi.swift new file mode 100644 index 0000000000..8a79f443e4 --- /dev/null +++ b/lowest-common-ancestor-of-a-binary-search-tree/radiantchoi.swift @@ -0,0 +1,33 @@ +// Definition for a binary tree node. +public class TreeNode { + public var val: Int + public var left: TreeNode? + public var right: TreeNode? + public init(_ val: Int) { + self.val = val + self.left = nil + self.right = nil + } +} + +class Solution { + func lowestCommonAncestor(_ root: TreeNode?, _ p: TreeNode?, _ q: TreeNode?) -> TreeNode? { + guard let p, let q else { return nil } + + var common = root + + // BST에서 같은 조상을 가진다는 건, 해당 조상의 "범주" 안에 있단 뜻 + // 왼쪽은 해당 값보다 작은 값, 오른쪽은 해당 값보다 큰 값이 있음을 보장 + while let ancestor = common, ancestor.val != p.val, ancestor.val != q.val { + if p.val < ancestor.val && q.val < ancestor.val { + common = common?.left + } else if p.val > ancestor.val && q.val > ancestor.val { + common = common?.right + } else { + break + } + } + + return common + } +} diff --git a/meeting-rooms-ii/radiantchoi.py b/meeting-rooms-ii/radiantchoi.py new file mode 100644 index 0000000000..5483aee986 --- /dev/null +++ b/meeting-rooms-ii/radiantchoi.py @@ -0,0 +1,40 @@ +import heapq + +from typing import ( + List, +) + +# 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: + # 이 문제에서는 회의 시작과 끝 시간이 interval이라는 별개의 객체로 정의되어 있음 + # Meeting Rooms 문제처럼, 시작 시간을 기준으로 미리 정렬 + intervals.sort(key=lambda x: x.start) + + # 현재 회의가 진행중인 방 갯수 + rooms = [] + + for current in intervals: + # 초기 설정 - 사용중인 방이 없다면, 그냥 추가 + # 빈 배열이므로 heappush를 사용할 필요는 없다 + if not rooms: + rooms.append(current.end) + else: + # 현재 진행 중인 회의 중 가장 빨리 끝나는 시간을 추출 + ending = heapq.heappop(rooms) + + # 현재 회의의 시작 시간이 가장 빨리 끝나는 회의보다 빠르다면, 해당 자리를 비울 수 없으므로 다시 힙에 삽입 + if current.start < ending: + heapq.heappush(rooms, ending) + + # 현재 회의가 끝나는 시간 삽입 + heapq.heappush(rooms, current.end) + + # 자연스럽게, 끝나는 시간들이 담긴 배열의 길이가 최소 회의실 갯수 + return len(rooms)