786 第k个数(快速选择算法)

该博客介绍了如何运用快速选择算法在给定长度为n的整数数列中找到第k小的数。通过分析题目,作者提出使用快速选择算法,该算法基于快速排序思想,通过选取主元并根据主元位置与k的关系来决定递归方向,以降低时间复杂度。代码实现中,定义了一个名为Solution的类,包含了快速选择算法的实现,并提供了findKthLargest方法用于输出第k小的元素。

1. 问题描述:

给定一个长度为 n 的整数数列,以及一个整数 k,请用快速选择算法求出数列从小到大排序后的第 k 个数。

输入格式

第一行包含两个整数 n 和 k。
第二行包含 n 个整数(所有整数均在 1∼10 ^ 9 范围内),表示整数数列。

输出格式

输出一个整数,表示数列的第 k 小数。

数据范围

1≤n≤100000,
1≤k≤n
输入样例:
5 3
2 4 1 5 3
输出样例:
3

来源:https://www.acwing.com/problem/content/description/788/

2. 思路分析:

分析题目可以知道我们需要在长度为n的数组中找到第k小的元素,在数组中找出第k小的元素可以使用快速选择算法,快速选择算法基于快速选择排序的思想(第k小的元素表示需要将元素从小到大进行调整),快速选择算法根据当前主元对应的位置与k的大小关系确定递归的位置,这样可以只递归一边,若当前主元的位置i大于等于k,说明答案应该是在i或者是i的左边,否则答案在i的右侧,可以参考力扣的215题,求解第k小与第k大的元素的方法都是一样的只是在比较的时候需要调整符号而已。

3. 代码如下:

from typing import List


class Solution:
    def quickSort(self, nums: List[int], low: int, high: int, k: int):
        if low >= high: return nums[low]
        t = nums[low]
        i, j = low, high
        while i < j:
            # nums[j] >= t为大于等于而不是大于, 求解的是第k小的数字所以需要将小于当前主元的数字放到前面, 第k小下面的判断是大于等于第k大是小于等于所以只需要调整符号即可判断
            while i < j and nums[j] >= t: j -= 1
            if i < j:
                nums[i] = nums[j]
                i += 1
            # 只有小于主元的元素指针才会被移动
            while i < j and nums[i] < t: i += 1
            if i < j:
                nums[j] = nums[i]
                j -= 1
        nums[i] = t
        # 根据i与k的关系决定递归的是哪一边
        if i >= k: return self.quickSort(nums, low, i, k)
        return self.quickSort(nums, i + 1, high, k)

    def findKthLargest(self, nums: List[int], k: int) -> int:
        return self.quickSort(nums, 0, len(nums) - 1, k - 1)


if __name__ == '__main__':
    n, k = map(int, input().split())
    nums = list(map(int, input().split()))
    print(Solution().findKthLargest(nums, k))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值