快速排序的扩展--数组中的第k个最大元素(leetcode:215)

快速排序的步骤

1.(partition过程) 以数组的最后一个元素作为参考值(pivot),大于这个元素的值的放右边,等于这个数的值放中间,小于这个数的值放左边。
2. 分别对小于pivot的数和大于pivot的数进行步骤1,并以此进行递归。

快速排序的代码

class QuickSort(object):
    def __init__(self):
        pass

    def quick_sort(self, arr):
        if len(arr) <= 1:
            return arr

        self.quick_sort_help(arr, 0, len(arr) - 1)

    def quick_sort_help(self, arr, left, right):
        if left < right:
            l, r = self.partition(arr, left, right)
            self.quick_sort_help(arr, left, l - 1)
            self.quick_sort_help(arr, r + 1, right)

    def partition(self, arr, left, right):
        less = left - 1
        more = right
        pivot = arr[right]
        index = left
        while index < more:
            if arr[index] < pivot:
                less += 1
                self.swap(arr, index, less)
                index += 1
            elif arr[index] > pivot:
                more -= 1
                self.swap(arr, index, more)
            else:
                index += 1
        self.swap(arr, right, more)
        return less + 1, more

    def swap(self, arr, i, j):
        arr[i], arr[j] = arr[j], arr[i]


if __name__ == '__main__':
    arr = [-42, 17, 32, -13, 31, 24, 27, -39, -26, -19]
    QuickSort().quick_sort(arr)
    print(arr)

运行结果如下所示:在这里插入图片描述

快速排序的扩展–数组中的第k个最大元素

问题描述:在未排序的数组中找到第 k 个最大的元素。
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
实例2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4

原理分析

在快速排序的partiton过程中,我们的选参考数(pivot)进行不严格排序(不是严格的按照大小顺序)。 我们把比pivot小的数放在左边,把比pivot大的数放在右边。 --> 这样可以得到一个重要信息:假设我们排序后的pivot的数下标为num,则pivot是整个数组中第num+1小的数,第(数组长度-num)大的数。并以此进行递归,直到pivot的下标(数组长度-num=k),输出pivot即可。
ps:为了效果更好,我们不妨随机选择pivot。

代码如下

from typing import List

class Solution(object):
    def findKthLargest(self, nums: List[int], k: int) -> int:
        if len(nums) < k:
            return 0
        index_id = len(nums) - k
        l, r = 0, len(nums) - 1
        left, right = self.partition(nums, l, r)

        while not left <= index_id <= right:
            if index_id < left:
                r = left - 1
            elif index_id > right:
                l = right + 1
            left, right = self.partition(nums, l, r)
        return nums[index_id]

    def partition(self, arr, left, right):
        less = left - 1
        more = right
        pivot = arr[right]
        index = left
        while index < more:
            if arr[index] < pivot:
                less += 1
                self.swap(arr, index, less)
                index += 1
            elif arr[index] > pivot:
                more -= 1
                self.swap(arr, index, more)
            else:
                index += 1
        self.swap(arr, right, more)
        return less + 1, more

    def swap(self, arr, i, j):
        arr[i], arr[j] = arr[j], arr[i]


if __name__ == '__main__':
    nums = [3, 2, 3, 1, 2, 4, 5, 5, 6]
    k = 4
    a = Solution().findKthLargest(nums, k)
    print(a)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值