package main
import (
"container/heap"
"fmt"
)
// IntHeap is a min-heap of ints
// Implements heap.Interface
// Len, Less, Swap, Push, Pop
type IntHeap []int
func (h IntHeap) Len() int { return len(h) }
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *IntHeap) Push(x interface{}) {
// add element to heap
*h = append(*h, x.(int))
}
func (h *IntHeap) Pop() interface{} {
// remove last element
n := len(*h)
x := (*h)[n-1]
*h = (*h)[:n-1]
return x
}
// kthSmallest returns the kth smallest element using a min heap
func kthSmallest(arr []int, k int) int {
h := &IntHeap{}
heap.Init(h) // organize heap before pushing elements
// build heap from array
for _, v := range arr {
heap.Push(h, v) // add all elements
}
var kth int
// extract min k times
for i := 0; i < k; i++ {
kth = heap.Pop(h).(int) // remove smallest
}
return kth
}
func main() {
arr := []int{7, 10, 4, 3, 20, 15}
k := 3
result := kthSmallest(arr, k)
fmt.Printf("%dth smallest element is %d\n", k, result)
}
for _, v := range arr {
heap.Push(h, v) // add all elements
}
Add all elements to the heap to prepare for extraction
heap.Init(h) // organize heap
Arrange elements so smallest is at the root
for i := 0; i < k; i++ {
kth = heap.Pop(h).(int) // remove smallest
}
Remove smallest element k times; last removed is kth smallest
3th smallest element is 7