合并 K 个升序链表 - 小根堆
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func mergeKLists(lists []*ListNode) *ListNode {
heap := NewMinHeap(len(lists))
for _, list := range lists {
if list != nil {
heap.Push(list)
}
}
dummy := &ListNode{}
prev := dummy
for heap.Size() > 0 {
top := heap.Pop()
if top.Next != nil {
heap.Push(top.Next)
}
prev.Next = top
prev = top
}
return dummy.Next
}
type MinHeap struct {
tree []*ListNode
}
func NewMinHeap(capacity int) *MinHeap {
return &MinHeap{
tree: make([]*ListNode, 0, capacity),
}
}
func (h *MinHeap) Size() int {
return len(h.tree)
}
func (h *MinHeap) Push(val *ListNode) {
h.tree = append(h.tree, val)
h.Up(h.Size() - 1)
}
func (h *MinHeap) Pop() *ListNode {
n := h.Size()
if n == 0 {
panic("heap is empty")
}
res := h.tree[0]
h.swap(0, n - 1)
h.tree = h.tree[:n - 1]
h.Down(0)
return res
}
func (h *MinHeap) Up(idx int) {
for {
parentIdx := (idx - 1) >> 1
if parentIdx < 0 {
break
}
if h.tree[idx].Val >= h.tree[parentIdx].Val {
break
}
h.swap(idx, parentIdx)
idx = parentIdx
}
}
func (h *MinHeap) Down(idx int) {
n := h.Size()
for {
minIdx := idx
leftChildIdx := (idx << 1) + 1
if leftChildIdx < n && h.tree[leftChildIdx].Val < h.tree[minIdx].Val {
minIdx = leftChildIdx
}
if leftChildIdx + 1 < n && h.tree[leftChildIdx + 1].Val < h.tree[minIdx].Val {
minIdx = leftChildIdx + 1
}
if minIdx == idx {
break
}
h.swap(idx, minIdx)
idx = minIdx
}
}
func (h *MinHeap) swap(a, b int) {
h.tree[a], h.tree[b] = h.tree[b], h.tree[a]
}