建堆
调整
删除
先根据数组构建完全二叉树
从第一个非叶结点开始 调整为大跟堆,这里就是图里面的1结点开始调整
代码如下:
func findKthLargest(nums []int, k int) int {
heapSize := len(nums)
buildMaxHeap(nums,heapSize)
for i := len(nums) - 1; i >= len(nums) - k + 1; i-- {
//堆顶出列 堆低补上
nums[0], nums[i] = nums[i], nums[0]
heapSize--
maxHeapify(nums,0,heapSize)
}
return nums[0]
}
func buildMaxHeap(a []int, heapSize int) {
//初始化大根堆
//非叶结点都堆排序一次 排序方式从尾到头
for i := heapSize / 2; i >= 0; i-- {
maxHeapify(a,i,heapSize)
}
}
// 大跟堆的调整
// 传入一个非叶结点
func maxHeapify(a []int, i ,heapSize int) {
l := i*2 + 1
r := i*2 + 2
largest := i
if l < heapSize && a[l] > a[largest] {
largest = l
}
if r < heapSize && a[r] > a[largest] {
largest = r
}
if largest != i {
a[i], a[largest] = a[largest], a[i]
//交换后的元素需要继续堆化
maxHeapify(a,largest,heapSize)
}
}
以此类推 运用上一个模板来再写一题
前K个高频元素
func topKFrequent(nums []int, k int) []int {
res := []int{}
hash := map[int]int{}
for i := range nums {
hash[nums[i]]++
}
//创建新数组
new := []int{}
for key := range hash {
new = append(new,key)
}
heapSize := len(new)
buildHeap(new, heapSize, hash)
for i := len(new) - 1; i >= len(new) - k; i-- {
res = append(res,new[0])
new[0], new[i] = new[i], new[0]
heapSize--
heapify(new,0,heapSize, hash)
}
return res
}
func buildHeap(a []int, heapSize int, hash map[int]int) {
for i := heapSize / 2; i >= 0; i-- {
heapify(a,i,heapSize, hash)
}
}
func heapify(a []int, i int, heapSize int, hash map[int]int) {
l := i*2 + 1
r := i*2 + 2
largest := i
if l < heapSize && hash[a[l]] > hash[a[largest]] {
largest = l
}
if r < heapSize && hash[a[r]] > hash[a[largest]] {
largest = r
}
if largest != i {
a[i], a[largest] = a[largest], a[i]
heapify(a,largest,heapSize, hash)
}
}