essay

hot100-数组中的第K个最大元素

#算法

hot100——数组中的第K个最大元素

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例 1:

  • 输入: [3,2,1,5,6,4], k = 2
  • 输出: 5

示例 2:

  • 输入: [3,2,3,1,2,4,5,5,6], k = 4
  • 输出: 4

提示:

1 <= k <= nums.length <= 10510^5

-10410^4 <= nums[i] <= 10410^4

解法

import "container/heap"
 
type MinHeap []int // 定义最小堆类型,底层使用切片
 
// --- 下面是必须实现的 heap.Interface 接口方法 ---
 
func (h MinHeap) Len() int { // Len 返回堆中元素的数量
    return len(h)
}
 
func (h MinHeap) Less(i, j int) bool { // Less 定义堆的排序规则
    return h[i] < h[j] // 对于最小堆,父节点的值应该小于子节点的值, 所以这里返回 h[i] < h[j]
}
 
func (h MinHeap) Swap(i, j int) { // Swap 交换两个索引位置的元素
    h[i], h[j] = h[j], h[i]
}
 
func (h *MinHeap) Push(x interface{}) { // Push 向堆中添加元素注意, 接收者是指针类型 *MinHeap,因为我们要修改切片的长度
    *h = append(*h, x.(int)) // 将 interface{} 类型断言为 int,然后追加到切片
}
 
func (h *MinHeap) Pop() interface{} { // Pop 从堆中移除并返回最后一个元素(堆顶), 注意:接收者是指针类型 *MinHeap
    top := (*h)[len(*h)-1] // 获取切片最后一个元素(即堆顶)(括号不能少)
    *h = (*h)[:len(*h)-1] // 切片截取,移除最后一个元素(括号不能少)
    return top
}
 
func findKthLargest(nums []int, k int) int {
    h := &MinHeap{}
    heap.Init(h) // 初始化堆,将切片调整为堆结构
    for _, num := range nums {
        if h.Len() < k {  // 情况1:如果堆中元素数量还没达到 k,直接入堆
            heap.Push(h, num)
        } else if num > (*h)[0] { // 情况2:堆已满,且当前数字 num 大于堆顶元素(堆中最小的),说明 num 有资格进入“前 k 大”的行列,而堆顶应该被淘汰
            heap.Pop(h)       // 弹出堆顶(淘汰最小的)
            heap.Push(h, num) // 新元素入堆
        }
        // 情况3:堆已满,但 num 小于等于堆顶,说明 num 不够大,直接忽略
    }
    return (*h)[0] // 遍历结束后,堆中保存的是最大的 k 个元素,堆顶 (*h)[0] 就是这 k 个元素中最小的,即整个数组的第 k 大元素(括号不能少)
}
comments如果有不同意见或者补充,直接留在这里。
contact

在别处继续找到我

如果你想聊技术、设计,或者只是打个招呼。

暂未配置外部链接