每日一道Leetcode - 215. 数组中的第K个最大元素 【构建大顶堆】

在这里插入图片描述

"""
先按照构建顺序将数组元素构建成一颗完全二叉树【层次排放】

从第一个非叶子结点为根节点的子树开始,将其调整为大根堆

调整倒数第二个非叶子结点作为根节点的子树

调整倒数第三个非叶子结点作为根节点的子树

调整完成之后在删除堆顶元素(k-1次),删除一次将末尾节点到堆顶位置再进行调整

最后返回堆顶元素

时间复杂度O(nlogn) 建堆时间代价为O(n),删除的总代价是O(klogn),k<n,渐进时间复杂度为O(n+klogn)

空间复杂度 O(logn), 递归使用栈空间的空间代价
"""
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        # 构建大顶堆
        self.buildMaxHeap(nums)
        # 找第K个 删除k-1次
        for _ in range(k-1):
            # 堆顶和堆尾首尾交换
            nums[0],nums[-1] = nums[-1],nums[0]
            # 弹出堆尾元素
            nums.pop()
            # 从堆头开始调整
            self.adjust_max_heap(nums,0)
        return nums[0]

    def buildMaxHeap(self,nums):
        # 从后往前遍历 即从第一个非叶子结点为根节点的子树开始调整大顶堆
        for in_node in range(len(nums)//2-1,-1,-1):
            # 调整大顶堆
            self.adjust_max_heap(nums,in_node)

    def adjust_max_heap(self,nums,in_node):
        # 从in_node节点开始调整 
        # in_node左节点索引 2*in_node+1 右节点索引 2*in_node+2
        # 假设当前子树最大值索引为in_node
        l,r,large_index = 2*in_node+1,2*in_node+2,in_node
        # 判断左节点和右节点哪个最大,且比当前large_index还要大,替换当前large_index的索引值
        if l<len(nums) and nums[l]>nums[large_index]:
            large_index = l
        if r<len(nums) and nums[r]>nums[large_index]:
            large_index = r
        # 如果large_index索引值变了,就要交换
        if large_index != in_node:
            nums[large_index],nums[in_node] = nums[in_node],nums[large_index]
            # 此时还要从large_index的节点处(原来的左/右节点)继续向下调整堆
            self.adjust_max_heap(nums,large_index)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值