Skip to content

Commit 9b5a2be

Browse files
committed
Create Solution.swift
1 parent 5458b9e commit 9b5a2be

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
class MedianFinder {
2+
private var minQ = Heap<Int>(sort: <)
3+
private var maxQ = Heap<Int>(sort: >)
4+
5+
init() {
6+
}
7+
8+
func addNum(_ num: Int) {
9+
maxQ.insert(num)
10+
minQ.insert(maxQ.remove()!)
11+
if maxQ.count < minQ.count {
12+
maxQ.insert(minQ.remove()!)
13+
}
14+
}
15+
16+
func findMedian() -> Double {
17+
if maxQ.count > minQ.count {
18+
return Double(maxQ.peek()!)
19+
}
20+
return (Double(maxQ.peek()!) + Double(minQ.peek()!)) / 2.0
21+
}
22+
}
23+
24+
struct Heap<T> {
25+
var elements: [T]
26+
let sort: (T, T) -> Bool
27+
28+
init(sort: @escaping (T, T) -> Bool, elements: [T] = []) {
29+
self.sort = sort
30+
self.elements = elements
31+
if !elements.isEmpty {
32+
for i in stride(from: elements.count / 2 - 1, through: 0, by: -1) {
33+
siftDown(from: i)
34+
}
35+
}
36+
}
37+
38+
var isEmpty: Bool {
39+
return elements.isEmpty
40+
}
41+
42+
var count: Int {
43+
return elements.count
44+
}
45+
46+
func peek() -> T? {
47+
return elements.first
48+
}
49+
50+
mutating func insert(_ value: T) {
51+
elements.append(value)
52+
siftUp(from: elements.count - 1)
53+
}
54+
55+
mutating func remove() -> T? {
56+
guard !elements.isEmpty else { return nil }
57+
elements.swapAt(0, elements.count - 1)
58+
let removedValue = elements.removeLast()
59+
siftDown(from: 0)
60+
return removedValue
61+
}
62+
63+
private mutating func siftUp(from index: Int) {
64+
var child = index
65+
var parent = parentIndex(ofChildAt: child)
66+
while child > 0 && sort(elements[child], elements[parent]) {
67+
elements.swapAt(child, parent)
68+
child = parent
69+
parent = parentIndex(ofChildAt: child)
70+
}
71+
}
72+
73+
private mutating func siftDown(from index: Int) {
74+
var parent = index
75+
while true {
76+
let left = leftChildIndex(ofParentAt: parent)
77+
let right = rightChildIndex(ofParentAt: parent)
78+
var candidate = parent
79+
if left < count && sort(elements[left], elements[candidate]) {
80+
candidate = left
81+
}
82+
if right < count && sort(elements[right], elements[candidate]) {
83+
candidate = right
84+
}
85+
if candidate == parent {
86+
return
87+
}
88+
elements.swapAt(parent, candidate)
89+
parent = candidate
90+
}
91+
}
92+
93+
private func parentIndex(ofChildAt index: Int) -> Int {
94+
return (index - 1) / 2
95+
}
96+
97+
private func leftChildIndex(ofParentAt index: Int) -> Int {
98+
return 2 * index + 1
99+
}
100+
101+
private func rightChildIndex(ofParentAt index: Int) -> Int {
102+
return 2 * index + 2
103+
}
104+
}
105+
106+
/**
107+
* Your MedianFinder object will be instantiated and called as such:
108+
* let obj = MedianFinder()
109+
* obj.addNum(num)
110+
* let ret_2: Double = obj.findMedian()
111+
*/

0 commit comments

Comments
 (0)