forked from yuyongwei/Algorithms-In-Swift
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathkthLargestElementInAStream.swift
More file actions
96 lines (81 loc) · 2.35 KB
/
Copy pathkthLargestElementInAStream.swift
File metadata and controls
96 lines (81 loc) · 2.35 KB
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
/*
Design a class to find the kth largest element in a stream. Note that it is the kth largest element in the sorted order, not the kth distinct element.
Your KthLargest class will have a constructor which accepts an integer k and an integer array nums, which contains initial elements from the stream. For each call to the method KthLargest.add, return the element representing the kth largest element in the stream.
https://leetcode.com/problems/kth-largest-element-in-a-stream/
*/
class KthLargest {
private let minHeap: MinHeap
init(_ k: Int, _ nums: [Int]) {
minHeap = MinHeap(capacity: k)
for i in nums {
minHeap.insert(i)
}
}
func add(_ val: Int) -> Int {
minHeap.insert(val)
return minHeap.min()
}
}
final class MinHeap {
private var pq: [Int]
private let MAX: Int
public init(capacity: Int) {
pq = [Int]()
MAX = capacity + 1
//insert fake head,
//heap index from 1
//so that we can calculate index easily
pq.append(0)
}
public func insert(_ k: Int) {
// when heap is full,
// only insert when k is greater than min()
if pq.count == MAX {
if k > min() {
deleteMin()
pq.append(k)
swim(pq.count-1)
}
} else {
// when heap is not full
// insert k, and swim
pq.append(k)
swim(pq.count-1)
}
}
public func min() -> Int {
return pq[1]
}
public func deleteMin() -> Int {
let min = pq[1]
exchange(1, pq.count-1)
pq.removeLast()
sink(1)
return min
}
//
private func sink(_ index: Int) {
var index = index
while 2 * index <= pq.count-1 {
var j = 2 * index
if j < pq.count-1 && pq[j] > pq[j+1] {
j = j + 1
}
if !(pq[index] > pq[j]) { break }
exchange(index, j)
index = j
}
}
private func swim(_ index: Int) {
var index = index
while index > 1 && pq[index/2] > pq[index] {
exchange(index/2, index)
index = index / 2
}
}
private func exchange(_ i: Int, _ j: Int) {
let temp = pq[i]
pq[i] = pq[j]
pq[j] = temp
}
}