Skip to content

Commit

Permalink
1985. Find the Kth Largest Integer in the Array
Browse files Browse the repository at this point in the history
  • Loading branch information
Mahim1997 committed Nov 7, 2022
1 parent 3cfb9a5 commit 3950604
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 0 deletions.
32 changes: 32 additions & 0 deletions java/1985-Find-The-Kth-Largest-Integer-In-The-Array.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Min Heap comparator for reverse priority queue
class StringNumberComparartor implements Comparator<String> {
@Override
public int compare(String s1, String s2) {
if(s1.length() != s2.length()) {
return (s1.length() - s2.length());
}
int len = s1.length();
for(int i=0; i<len; i++) {
char c1 = s1.charAt(i), c2 = s2.charAt(i);
if(c1 == c2) { continue; }
return (c1 - c2);
}
return 0;
}
}

class Solution {
public String kthLargestNumber(String[] nums, int k) {
// Reverse pq to store only k elements [i.e. Min Heap]
PriorityQueue<String> pq = new PriorityQueue<>(new StringNumberComparartor());

for(String numStr: nums) {
pq.add(numStr);
if(pq.size() > k) {
pq.remove();
}
}

return pq.peek();
}
}
143 changes: 143 additions & 0 deletions swift/1985-Find-The-Kth-Largest-Integer-In-The-Array.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
class Solution {
func kthLargestNumber(_ nums: [String], _ k: Int) -> String {
// Use a Min Heap for storing upto k-elements max in the priority queue
var heap: Heap<String> = Heap(sort: { (str1, str2) in
guard str1.count == str2.count else { return str1.count < str2.count }
for (c1, c2) in zip(str1, str2) {
guard c1 == c2 else { return c1 < c2 }
}
return false
})

nums.forEach { num in
heap.insert(num)
if heap.count > k {
heap.remove()
}
}

return heap.peek() ?? ""
}
}

// Heap used from https://github.com/kodecocodes/swift-algorithm-club/blob/master/Heap/Heap.swift
public struct Heap<T> {
var nodes = [T]()

private var orderCriteria: (T, T) -> Bool

public init(sort: @escaping (T, T) -> Bool) {
self.orderCriteria = sort
}

public init(array: [T], sort: @escaping (T, T) -> Bool) {
self.orderCriteria = sort
configureHeap(from: array)
}

private mutating func configureHeap(from array: [T]) {
nodes = array
for i in stride(from: (nodes.count/2-1), through: 0, by: -1) {
shiftDown(i)
}
}

public var isEmpty: Bool {
return nodes.isEmpty
}

public var count: Int {
return nodes.count
}

@inline(__always) internal func parentIndex(ofIndex i: Int) -> Int {
return (i - 1) / 2
}

@inline(__always) internal func leftChildIndex(ofIndex i: Int) -> Int {
return 2*i + 1
}

@inline(__always) internal func rightChildIndex(ofIndex i: Int) -> Int {
return 2*i + 2
}

public func peek() -> T? {
return nodes.first
}

public mutating func insert(_ value: T) {
nodes.append(value)
shiftUp(nodes.count - 1)
}

public mutating func insert<S: Sequence>(_ sequence: S) where S.Iterator.Element == T {
for value in sequence {
insert(value)
}
}

public mutating func replace(index i: Int, value: T) {
guard i < nodes.count else { return }
remove(at: i)
insert(value)
}

@discardableResult public mutating func remove() -> T? {
guard !nodes.isEmpty else { return nil }
if nodes.count == 1 {
return nodes.removeLast()
} else {
let value = nodes[0]
nodes[0] = nodes.removeLast()
shiftDown(0)
return value
}
}

@discardableResult public mutating func remove(at index: Int) -> T? {
guard index < nodes.count else { return nil }
let size = nodes.count - 1
if index != size {
nodes.swapAt(index, size)
shiftDown(from: index, until: size)
shiftUp(index)
}
return nodes.removeLast()
}

internal mutating func shiftUp(_ index: Int) {
var childIndex = index
let child = nodes[childIndex]
var parentIndex = self.parentIndex(ofIndex: childIndex)

while childIndex > 0 && orderCriteria(child, nodes[parentIndex]) {
nodes[childIndex] = nodes[parentIndex]
childIndex = parentIndex
parentIndex = self.parentIndex(ofIndex: childIndex)
}

nodes[childIndex] = child
}

internal mutating func shiftDown(from index: Int, until endIndex: Int) {
let leftChildIndex = self.leftChildIndex(ofIndex: index)
let rightChildIndex = leftChildIndex + 1

var first = index
if leftChildIndex < endIndex && orderCriteria(nodes[leftChildIndex], nodes[first]) {
first = leftChildIndex
}
if rightChildIndex < endIndex && orderCriteria(nodes[rightChildIndex], nodes[first]) {
first = rightChildIndex
}
if first == index { return }

nodes.swapAt(index, first)
shiftDown(from: first, until: endIndex)
}

internal mutating func shiftDown(_ index: Int) {
shiftDown(from: index, until: nodes.count)
}
}

0 comments on commit 3950604

Please sign in to comment.