// This example demonstrates a priority queue built using the heap interface.
package main
import (
"container/heap"
"fmt"
)
// An Item is something we manage in a priority queue.
type Item struct {
value int // The value of the item; arbitrary.
priority int // The priority of the item in the queue.
// The index is needed by update and is maintained by the heap.Interface methods.
index int // The index of the item in the heap.
}
// A PriorityQueue implements heap.Interface and holds Items.
type PriorityQueue []*Item
func (pq PriorityQueue) Len() int { return len(pq) }
func (pq PriorityQueue) Less(i, j int) bool {
// We want Pop to give us the highest, not lowest, priority so we use greater than here.
return pq[i].value > pq[j].value
}
func (pq PriorityQueue) Swap(i, j int) {
pq[i], pq[j] = pq[j], pq[i]
pq[i].index = j
pq[j].index = i
}
func (pq *PriorityQueue) Push(x interface{}) {
n := len(*pq)
item := x.(*Item)
item.index = n
*pq = append(*pq, item)
}
func (pq *PriorityQueue) Pop() interface{} {
old := *pq
n := len(old)
item := old[n-1]
item.index = -1 // for safety
*pq = old[0 : n-1]
return item
}
// update modifies the priority and value of an Item in the queue.
func (pq *PriorityQueue) update(item *Item, value int, priority int) {
item.value = value
item.priority = priority
heap.Fix(pq, item.index)
}
func main() {
nums := []int{1, 3, 2, -3, 5, 3, 6, 7, 8, 9}
k := 3
result := maxSlidingWindow(nums, k)
fmt.Println("result", result)
}
func maxSlidingWindow(nums []int, k int) {
pq := make(PriorityQueue, len(nums))
res := []int{}
for i := 0; i < k; i++ {
pq[i] = &Item{
value: nums[i],
priority: nums[i],
index: i,
}
res = append(res, nums[i])
}
heap.Init(&pq)
peek := pq[0]
fmt.Println(peek.value) // its a maxheap and gives the largest element
temp := heap.Pop(&pq).(*Item)
fmt.Println("temp:", temp)
remove := heap.Remove(&pq, 0).(*Item)
// pq = slices.Delete(pq, 5)
fmt.Println("remove:", remove)
for i:=0;i<len(nums);i++{
//remove the desired element from the priority Queue
// insert the next element in the Priority queue
// peek the highest value
}
}
I am trying to print the maximum value in a sliding window. Putting the elements of window size, here k = 3 into the priority queue(Maxheap) and then peek the value. "heap.Init(&pq)" will assign the index in pq based on the priority. Look for maxSlidingWindow function, the last for loop prints the max element for each window of size k. If you compare the indices in the pq and the nums array the indices will be different. And hence deleting the desired element from the priority queue seems almost impossible.
Your question is not clear enough. I assume that you want your
maxSlidingWindow
to behave like this:To achieve this, one might do the following:
Fill a priority queue with the first
k
values fromnums
.Your code is putting all values from
nums
into the queue, which does not seem like a moving window approach. And I do doubt if I misunderstand your question.Take the max value from the queue, append it to the
result
.For i from
k
tolen(Data) - 1
:Discard the
nums[i-k]
element from the priority queue, and push into the queuenums[i]
.You should use use
heap.Remove
to remove an element. Go'sheap.Fix
provides a way to combine the removing and pushing steps.Take the max value of the modified priority queue, append it to the
result
.Also, your implementation of the queue has a bug:
Removing elements from priority queues
According to the title of the question, it seems you cannot get this part working:
Using Go's
heap
, to modify an item (withheap.Fix
) or remove one (withheap.Remove
, an index to that item is required. To get the corresponding index, there are at least two ways.Note that we need to distinguish from the indices of elements in
nums
and the indices of elements in the queue. I am to refer to the former one asi
in the following code and the latter,j
. We know thei
of the element we want to remove, but sinceheap
changes the queue, we need to findj
.Loop through the queue and find the element
Simple enough. In this way, you may just simplify the
PriorityQueue
type:It handles duplicate values correctly.
Keep a external
i -> j
mappingBelow is just a possible way doing it and may not be that elegant. I use a
CircularArray
to keep our mapping: