Skip to content

Commit 17e8042

Browse files
authored
Merge pull request #2316 from radiantchoi/main
[radiantchoi] WEEK 13 Solutions
2 parents eb43dc4 + 522b40d commit 17e8042

2 files changed

Lines changed: 152 additions & 0 deletions

File tree

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Definition for a binary tree node.
2+
public class TreeNode {
3+
public var val: Int
4+
public var left: TreeNode?
5+
public var right: TreeNode?
6+
public init() { self.val = 0; self.left = nil; self.right = nil; }
7+
public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
8+
public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
9+
self.val = val
10+
self.left = left
11+
self.right = right
12+
}
13+
}
14+
15+
class Solution {
16+
// 자체 풀이 - heapq를 구현하고, 그에 따라 트리의 모든 원소를 꺼내서 넣은 다음, k에 도달할 때까지 뽑아내는 방식
17+
// 모든 종류의 이진 트리에 적용 가능
18+
func kthSmallest(_ root: TreeNode?, _ k: Int) -> Int {
19+
var heapq = HeapQ<Int>(criteria: <)
20+
extractElement(root, &heapq)
21+
22+
var result: Int? = nil
23+
24+
for _ in 0..<k {
25+
result = heapq.pop()
26+
}
27+
28+
return result ?? 0
29+
}
30+
31+
func extractElement(_ root: TreeNode?, _ heapq: inout HeapQ<Int>) {
32+
guard let root else { return }
33+
34+
heapq.push(root.val)
35+
36+
extractElement(root.left, &heapq)
37+
extractElement(root.right, &heapq)
38+
}
39+
}
40+
41+
struct HeapQ<Element> {
42+
var storage: [Element]
43+
var criteria: (Element, Element) -> Bool
44+
45+
var isEmpty: Bool {
46+
storage.isEmpty
47+
}
48+
49+
init(
50+
storage: [Element] = [],
51+
criteria: @escaping (Element, Element) -> Bool
52+
) {
53+
self.storage = storage
54+
self.criteria = criteria
55+
}
56+
57+
mutating func push(_ element: Element) {
58+
storage.append(element)
59+
siftUp(from: storage.endIndex - 1)
60+
}
61+
62+
mutating func pop() -> Element? {
63+
guard !isEmpty else { return nil }
64+
65+
storage.swapAt(0, storage.endIndex - 1)
66+
67+
defer {
68+
if !isEmpty {
69+
siftDown(from: 0)
70+
}
71+
}
72+
73+
return storage.removeLast()
74+
}
75+
76+
private mutating func siftUp(from index: Int) {
77+
var parent = (index - 1) / 2
78+
var child = index
79+
80+
while child > 0 && criteria(storage[child], storage[parent]) {
81+
storage.swapAt(parent, child)
82+
child = parent
83+
parent = (child - 1) / 2
84+
}
85+
}
86+
87+
private mutating func siftDown(from index: Int) {
88+
var parent = index
89+
90+
while true {
91+
let left = 2 * parent + 1
92+
let right = 2 * parent + 2
93+
var candidate = parent
94+
95+
if left < storage.count && criteria(storage[left], storage[candidate]) {
96+
candidate = left
97+
}
98+
99+
if right < storage.count && criteria(storage[right], storage[candidate]) {
100+
candidate = right
101+
}
102+
103+
if candidate == parent { return }
104+
105+
storage.swapAt(parent, candidate)
106+
parent = candidate
107+
}
108+
}
109+
110+
// AI와 논의한 풀이: BST의 성질을 이용해 중위 탐색을 수행
111+
// 원소를 일반 배열에 삽입함으로써, 삽입시마다 O(logN)의 시간복잡도를 갖지 않고 O(1)의 시간복잡도를 가짐
112+
// 중위 탐색: 왼쪽 서브트리 - 자기 자신 - 오른쪽 서브트리 순으로 탐색
113+
func kthSmallest2(_ root: TreeNode?, _ k: Int) -> Int {
114+
var values: [Int] = []
115+
traverse(root, &values, k)
116+
117+
return values[k - 1]
118+
}
119+
120+
func traverse(_ node: TreeNode?, _ values: inout [Int], _ threshold: Int) {
121+
guard let node, values.count < threshold else { return }
122+
traverse(node.left, &values, threshold)
123+
124+
guard values.count < threshold else { return }
125+
values.append(node.val)
126+
127+
traverse(node.right, &values, threshold)
128+
}
129+
}

meeting-rooms/radiantchoi.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from typing import (
2+
List,
3+
)
4+
5+
# Definition of Interval:
6+
class Interval(object):
7+
def __init__(self, start, end):
8+
self.start = start
9+
self.end = end
10+
11+
12+
class Solution:
13+
def can_attend_meetings(self, intervals: List[Interval]) -> bool:
14+
intervals = sorted(intervals, key=lambda x: x.start)
15+
16+
for i in range(1, len(intervals)):
17+
prev = intervals[i - 1]
18+
current = intervals[i]
19+
20+
if prev.end > current.start:
21+
return False
22+
23+
return True

0 commit comments

Comments
 (0)