数组中的第K个最大元素 -- 堆&快排

这篇博客介绍了如何在Python中解决LeetCode的215题——数组中的第K个最大元素。提供了三种解决方案:小根堆、大根堆和快速选择。小根堆方法在O(N*logK)的时间复杂度内找到结果,大根堆则为O(N*logN),而快速选择算法的时间复杂度为O(N)。每种方法的空间复杂度也有所不同,分别为O(K)、O(N)和O(N)。
摘要由CSDN通过智能技术生成

题目描述

LeetCode链接:数组中的第K个最大元素

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

在这里插入图片描述

class FindKthLargest:
    """
    https://leetcode.cn/problems/kth-largest-element-in-an-array/
    215. 数组中的第K个最大元素
    """

    def solution1(self, k: int, nums: List[int]):
        """
        小根堆
        构建一个大小为K的小根堆,放入K个元素。遍历元素,大于堆顶加入堆,维护堆的大小为k。
        最后堆顶即可第k大元素。
        时间复杂度:O(N*logK)
        空间复杂度:O(K)
        :param k:
        :param nums:
        :return:
        """
        min_heap = []
        for num in nums:
            heapq.heappush(min_heap, num)
            if len(min_heap) > k:
                heapq.heappop(min_heap)
        return min_heap[0]

    def solution2(self, k: int, nums: List[int]):
        """
        大根堆
        所有元素都放入堆,最后pop()k次即可。
        时间复杂度:O(N*logN)
        空间复杂度:O(N)
        :param k:
        :param nums:
        :return:
        """
        max_heap = []
        # 所有元素都放入堆
        for num in nums:
            heapq.heappush(max_heap, -num)

        res = None
        for _ in range(k):
            res = -heapq.heappop(max_heap)
        return res

    def solution3(self, k: int, nums: List[int]):
        """
        快排
        时间复杂度:O(N)
        空间复杂度:O(N)
        :return:
        """
        return self.findK(nums, k, 0, len(nums)-1)

    def findK(self, nums, k, low, high):
        if low == high:
            return nums[low]

        partition = self.quickSortOneTime(nums, low, high)
        # 找到的是第几个大值
        idx = high - partition + 1
        if idx == k:
            return nums[partition]
        elif idx < k:
            return self.findK(nums, k-idx, low, partition-1)
        else:
            return self.findK(nums, k, partition+1, high)

    def quickSortOneTime(self, nums, low, high):
        """
        一趟快速排序,即【快速选择】
        :param nums:
        :param low:
        :param high:
        :return:
        """
        k_value = nums[low]
        while low < high:
            while k_value < nums[high] and low < high:
                high -= 1
            nums[low] = nums[high]

            while k_value >= nums[low] and low < high:
                low += 1
            nums[high] = nums[low]

        nums[high] = k_value
        return high

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NLP_wendi

谢谢您的支持。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值