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. count else { return str1. count < str2. count }
6
+ for (c1, c2) in zip ( str1, str2) {
7
+ guard c1 == c2 else { return c1 < c2 }
8
+ }
9
+ return false
10
+ } )
11
+
12
+ nums. forEach { num in
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. count else { return }
82
+ remove ( at: i)
83
+ insert ( value)
84
+ }
85
+
86
+ @discardableResult public mutating func remove( ) -> T ? {
87
+ guard !nodes. isEmpty else { 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. count else { 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
+ }
0 commit comments