Skip to content

Commit fb5b707

Browse files
authored
Merge pull request neetcode-gh#1441 from Mahim1997/dev/1985_Java_Swift
1985. Find the Kth Largest Integer in the Array
2 parents fc52900 + 3950604 commit fb5b707

File tree

2 files changed

+175
-0
lines changed

2 files changed

+175
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Min Heap comparator for reverse priority queue
2+
class StringNumberComparartor implements Comparator<String> {
3+
@Override
4+
public int compare(String s1, String s2) {
5+
if(s1.length() != s2.length()) {
6+
return (s1.length() - s2.length());
7+
}
8+
int len = s1.length();
9+
for(int i=0; i<len; i++) {
10+
char c1 = s1.charAt(i), c2 = s2.charAt(i);
11+
if(c1 == c2) { continue; }
12+
return (c1 - c2);
13+
}
14+
return 0;
15+
}
16+
}
17+
18+
class Solution {
19+
public String kthLargestNumber(String[] nums, int k) {
20+
// Reverse pq to store only k elements [i.e. Min Heap]
21+
PriorityQueue<String> pq = new PriorityQueue<>(new StringNumberComparartor());
22+
23+
for(String numStr: nums) {
24+
pq.add(numStr);
25+
if(pq.size() > k) {
26+
pq.remove();
27+
}
28+
}
29+
30+
return pq.peek();
31+
}
32+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
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

Comments
 (0)