forked from neetcode-gh/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
0703-kth-largest-element-in-a-stream.swift
129 lines (113 loc) · 3.33 KB
/
0703-kth-largest-element-in-a-stream.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Heap source code at: https://gist.github.com/kalub92/d269ba6b2bf05ca7dcbaae64b4ff7a2d
struct MinHeap {
var items: [Int] = []
//Get Index
private func getLeftChildIndex(_ parentIndex: Int) -> Int {
return 2 * parentIndex + 1
}
private func getRightChildIndex(_ parentIndex: Int) -> Int {
return 2 * parentIndex + 2
}
private func getParentIndex(_ childIndex: Int) -> Int {
return (childIndex - 1) / 2
}
// Boolean Check
private func hasLeftChild(_ index: Int) -> Bool {
return getLeftChildIndex(index) < items.count
}
private func hasRightChild(_ index: Int) -> Bool {
return getRightChildIndex(index) < items.count
}
private func hasParent(_ index: Int) -> Bool {
return getParentIndex(index) >= 0
}
// Return Item From Heap
private func leftChild(_ index: Int) -> Int {
return items[getLeftChildIndex(index)]
}
private func rightChild(_ index: Int) -> Int {
return items[getRightChildIndex(index)]
}
private func parent(_ index: Int) -> Int {
return items[getParentIndex(index)]
}
// Heap Operations
mutating private func swap(indexOne: Int, indexTwo: Int) {
let placeholder = items[indexOne]
items[indexOne] = items[indexTwo]
items[indexTwo] = placeholder
}
public func peek() -> Int {
if items.count != 0 {
return items[0]
} else {
fatalError()
}
}
mutating public func poll() -> Int {
if items.count != 0 {
let item = items[0]
items[0] = items[items.count - 1]
heapifyDown()
items.removeLast()
return item
} else {
fatalError()
}
}
mutating public func add(_ item: Int) {
items.append(item)
heapifyUp()
}
mutating private func heapifyUp() {
var index = items.count - 1
while hasParent(index) && parent(index) > items[index] {
swap(indexOne: getParentIndex(index), indexTwo: index)
index = getParentIndex(index)
}
}
mutating private func heapifyDown() {
var index = 0
while hasLeftChild(index) {
var smallerChildIndex = getLeftChildIndex(index)
if hasRightChild(index) &&
rightChild(index) < leftChild(index) {
smallerChildIndex = getRightChildIndex(index)
}
if items[index] < items[smallerChildIndex] {
break
} else {
swap(indexOne: index, indexTwo: smallerChildIndex)
}
index = smallerChildIndex
}
}
}
// Extensions to add for the required problem
extension MinHeap {
var size: Int { items.count }
}
class KthLargest {
var minHeap = MinHeap()
var capacity = 0
init(_ k: Int, _ nums: [Int]) {
self.capacity = k
nums.forEach { add($0) }
}
func add(_ val: Int) -> Int {
if minHeap.size >= capacity {
if val > minHeap.peek() {
minHeap.poll()
minHeap.add(val)
}
} else {
minHeap.add(val)
}
return minHeap.peek()
}
}
/**
* Your KthLargest object will be instantiated and called as such:
* let obj = KthLargest(k, nums)
* let ret_1: Int = obj.add(val)
*/