Greetings, aspiring Go developer! Today, we're diving into high-level data manipulation with a crucial data structure in Go — heaps. Heaps are powerful for implementing efficient algorithms, particularly in finding quick median solutions. In Go, we leverage the container/heap
package to manage heap operations effectively. Ready to explore how heaps can simplify complex algorithmic challenges? Let's dive in!
Your task is to create a Go function named PrefixMedian
that takes an array of unique integers as input. The integers will range from 1 to (10^6), and the array length will be between 1 and 1000. The function should return a slice consisting of the medians of all prefixes of the input array.
A prefix of an array is a contiguous subsequence starting from the first element. The median of a sequence of numbers is the middle value when sorted. If the sequence has an even length, the median is the element in the position length / 2 - 1
.
For example, given the input array [1, 9, 2, 8, 3]
, the output should be [1, 1, 2, 2, 3]
.
In Go, heaps are managed using the container/heap
package, enabling us to perform heap operations efficiently. A Min Heap maintains its smallest element at the root, while a Max Heap maintains its largest. Using Min and Max Heaps together is an effective way to dynamically calculate medians as elements are processed.
In Go, we leverage the container/heap
package to handle heap operations. Here's how to implement Min Heap and Max Heap using interfaces and heap operations:
Go1package main 2 3import ( 4 "container/heap" 5 "fmt" 6) 7 8type MinHeap []int 9 10func (h MinHeap) Len() int { return len(h) } 11func (h MinHeap) Less(i, j int) bool { return h[i] < h[j] } 12func (h MinHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } 13 14func (h *MinHeap) Push(x interface{}) { 15 *h = append(*h, x.(int)) 16} 17 18func (h *MinHeap) Pop() interface{} { 19 old := *h 20 n := len(old) 21 x := old[n-1] 22 *h = old[0 : n-1] 23 return x 24} 25 26type MaxHeap []int 27 28func (h MaxHeap) Len() int { return len(h) } 29func (h MaxHeap) Less(i, j int) bool { return h[i] > h[j] } 30func (h MaxHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } 31 32func (h *MaxHeap) Push(x interface{}) { 33 *h = append(*h, x.(int)) 34} 35 36func (h *MaxHeap) Pop() interface{} { 37 old := *h 38 n := len(old) 39 x := old[n-1] 40 *h = old[0 : n-1] 41 return x 42}
Now that we have the heap structures in place, let's initialize them along with a slice to store the medians.
Go1func PrefixMedian(arr []int) []int { 2 maxHeap := &MaxHeap{} 3 minHeap := &MinHeap{} 4 heap.Init(maxHeap) 5 heap.Init(minHeap) 6 medians := make([]int, len(arr)) 7}
As we iterate through the array, we decide which heap to add each element to, using Go idioms. Finally, store the medians during each step. In cases where heap sizes are equal, take the median from maxHeap
, otherwise from minHeap
:
Go1func PrefixMedian(arr []int) []int { 2 maxHeap := &MaxHeap{} 3 minHeap := &MinHeap{} 4 heap.Init(maxHeap) 5 heap.Init(minHeap) 6 medians := make([]int, len(arr)) 7 8 for i, num := range arr { 9 if maxHeap.Len() > 0 && num < (*maxHeap)[0] { 10 heap.Push(maxHeap, num) 11 } else { 12 heap.Push(minHeap, num) 13 } 14 15 // Balance the heaps 16 if maxHeap.Len() > minHeap.Len()+1 { 17 heap.Push(minHeap, heap.Pop(maxHeap)) 18 } else if minHeap.Len() > maxHeap.Len() { 19 heap.Push(maxHeap, heap.Pop(minHeap)) 20 } 21 22 // Extract median 23 if maxHeap.Len() == minHeap.Len() { 24 medians[i] = (*maxHeap)[0] 25 } else { 26 medians[i] = (*minHeap)[0] 27 } 28 } 29 30 return medians 31} 32 33func main() { 34 arr := []int{1, 9, 2, 8, 3} 35 medians := PrefixMedian(arr) 36 fmt.Println("Final Medians Array:") 37 for _, median := range medians { 38 fmt.Printf("%d ", median) 39 } 40}
Congratulations! You've tackled an algorithmic challenge using Go's container/heap
package to handle heaps efficiently. This approach not only enhances your understanding of Go's powerful built-in packages but also strengthens your skills in algorithmic problem-solving. Keep practicing with similar problems to master data-structure management and efficient coding techniques in Go. Happy coding!