1
+ class Solution {
2
+ func kthLargestNumber( _ nums: [ String ] , _ k: Int ) -> String {
3
+ // Use a Min Heap for storing upto k-elements max in the priority queue
4
+ var heap : Heap < String > = Heap ( sort: { ( str1, str2) in
5
+ guard str1. count== str2. countelse { return str1. count< str2. count}
6
+ for (c1, c2) in zip ( str1, str2) {
7
+ guard c1== c2else { return c1< c2}
8
+ }
9
+ return false
10
+ } )
11
+
12
+ nums. forEach { numin
13
+ heap. insert ( num)
14
+ if heap. count> k{
15
+ heap. remove ( )
16
+ }
17
+ }
18
+
19
+ return heap. peek ( ) ?? " "
20
+ }
21
+ }
22
+
23
+ // Heap used from https://github.com/kodecocodes/swift-algorithm-club/blob/master/Heap/Heap.swift
24
+ public struct Heap < T> {
25
+ var nodes = [ T] ( )
26
+
27
+ private var orderCriteria : ( T , T ) -> Bool
28
+
29
+ public init ( sort: @escaping ( T , T ) -> Bool ) {
30
+ self . orderCriteria= sort
31
+ }
32
+
33
+ public init ( array: [ T ] , sort: @escaping ( T , T ) -> Bool ) {
34
+ self . orderCriteria= sort
35
+ configureHeap ( from: array)
36
+ }
37
+
38
+ private mutating func configureHeap( from array: [ T ] ) {
39
+ nodes= array
40
+ for i in stride ( from: ( nodes. count/ 2 - 1 ) , through: 0 , by: - 1 ) {
41
+ shiftDown ( i)
42
+ }
43
+ }
44
+
45
+ public var isEmpty : Bool {
46
+ return nodes. isEmpty
47
+ }
48
+
49
+ public var count : Int {
50
+ return nodes. count
51
+ }
52
+
53
+ @inline ( __always) internal func parentIndex( ofIndex i: Int ) -> Int {
54
+ return ( i- 1 ) / 2
55
+ }
56
+
57
+ @inline ( __always) internal func leftChildIndex( ofIndex i: Int ) -> Int {
58
+ return 2 * i+ 1
59
+ }
60
+
61
+ @inline ( __always) internal func rightChildIndex( ofIndex i: Int ) -> Int {
62
+ return 2 * i+ 2
63
+ }
64
+
65
+ public func peek( ) -> T ? {
66
+ return nodes. first
67
+ }
68
+
69
+ public mutating func insert( _ value: T ) {
70
+ nodes. append ( value)
71
+ shiftUp ( nodes. count- 1 )
72
+ }
73
+
74
+ public mutating func insert< S: Sequence > ( _ sequence: S ) where S. Iterator. Element== T {
75
+ for value in sequence{
76
+ insert ( value)
77
+ }
78
+ }
79
+
80
+ public mutating func replace( index i: Int , value: T ) {
81
+ guard i< nodes. countelse { return }
82
+ remove ( at: i)
83
+ insert ( value)
84
+ }
85
+
86
+ @discardableResult public mutating func remove( ) -> T ? {
87
+ guard !nodes. isEmptyelse { return nil }
88
+ if nodes. count== 1 {
89
+ return nodes. removeLast ( )
90
+ } else {
91
+ let value = nodes [ 0 ]
92
+ nodes [ 0 ] = nodes. removeLast ( )
93
+ shiftDown ( 0 )
94
+ return value
95
+ }
96
+ }
97
+
98
+ @discardableResult public mutating func remove( at index: Int ) -> T ? {
99
+ guard index< nodes. countelse { return nil }
100
+ let size = nodes. count- 1
101
+ if index!= size{
102
+ nodes. swapAt ( index, size)
103
+ shiftDown ( from: index, until: size)
104
+ shiftUp ( index)
105
+ }
106
+ return nodes. removeLast ( )
107
+ }
108
+
109
+ internal mutating func shiftUp( _ index: Int ) {
110
+ var childIndex = index
111
+ let child = nodes [ childIndex]
112
+ var parentIndex = self . parentIndex ( ofIndex: childIndex)
113
+
114
+ while childIndex> 0 &&orderCriteria ( child, nodes [ parentIndex] ) {
115
+ nodes [ childIndex] = nodes [ parentIndex]
116
+ childIndex= parentIndex
117
+ parentIndex= self . parentIndex ( ofIndex: childIndex)
118
+ }
119
+
120
+ nodes [ childIndex] = child
121
+ }
122
+
123
+ internal mutating func shiftDown( from index: Int , until endIndex: Int ) {
124
+ let leftChildIndex = self . leftChildIndex ( ofIndex: index)
125
+ let rightChildIndex = leftChildIndex+ 1
126
+
127
+ var first = index
128
+ if leftChildIndex< endIndex &&orderCriteria ( nodes [ leftChildIndex] , nodes [ first] ) {
129
+ first= leftChildIndex
130
+ }
131
+ if rightChildIndex< endIndex &&orderCriteria ( nodes [ rightChildIndex] , nodes [ first] ) {
132
+ first= rightChildIndex
133
+ }
134
+ if first== index{ return }
135
+
136
+ nodes. swapAt ( index, first)
137
+ shiftDown ( from: first, until: endIndex)
138
+ }
139
+
140
+ internal mutating func shiftDown( _ index: Int ) {
141
+ shiftDown ( from: index, until: nodes. count)
142
+ }
143
+ }