215. Kth Largest Element in an Array(python+cpp)

本文探讨了在未排序数组中查找第k大元素的有效算法,包括直接排序、分治策略和堆排序三种方法。通过Python和C++代码实现,对比了不同算法的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
Example 1:

Input: [3,2,1,5,6,4] and k = 2 
Output: 5 

Example 2:

Input: [3,2,3,1,2,4,5,5,6] and k = 4 
Output: 4 

Note: You may assumek is always valid, 1 ≤ k ≤ array's length.

解释:
返回数组中第k个最大元素,也就是数组升序排序后,从右往左数的第k个数字(k从1开始),与第k大的数(排序后从左往右数,k从0开始)意义不同。
解法1,排序后返回,速度很快:

class Solution(object):
    def findKthLargest(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        return sorted(nums,reverse=True)[k-1]

解法2:分治思想,用partition做,按理说速度应该很快才对为什么这么慢…(我记得在牛客网上用python实现第k大的数最后超时了),剑指offer上是说一般的排序算法的时间复杂度是O(nlogn),然而用partition做时间复杂度必然是低于快速排序的,可能这里是因为成熟语言的排序算法用了和一般排序算法不一样的策略,所以速度更快。
python代码:

class Solution(object):
    def findKthLargest(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        def partition(nums,left,right):
            pivot=nums[left]
            while left<right:
                while left<right and nums[right]>=pivot:
                    right-=1
                nums[left]=nums[right]
                while left<right and nums[left]<=pivot:
                    left+=1
                nums[right]=nums[left]
            nums[left]=pivot
            return left
        if k<0 or k>len(nums):
            return 
        left=0
        right=len(nums)-1
        mid=partition(nums,left,right)
        key=len(nums)-k
        while mid!=key:
            if mid<key:
                mid=partition(nums,mid+1,right)
            else:
                mid=partition(nums,left,mid-1)
        return nums[mid]

c++代码:

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        int n=nums.size();
        int left=0,right=n-1;
        int key=n-k;
        int mid=partition(nums,left,right);
        while (mid!=key)
        {
            if(mid>key)
                mid=partition(nums,left,mid-1);
            else
                mid=partition(nums,mid+1,right);
        }
        return nums[mid];
    }
    int  partition(vector<int>&nums,int left,int right)
    {
        int pivot=nums[left];
        while (left<right)
        {
            while(left<right && nums[right]>=pivot)
                right--;
            nums[left]=nums[right];
            while(left<right && nums[left]<=pivot)
                left++;
            nums[right]=nums[left];
        }
        nums[left]=pivot;
        return left;
    }
};

解法3:使用堆排序,速度相当快。

import heapq
class Solution(object):
    def findKthLargest(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        return heapq.nlargest(k,nums)[-1];

总结
python的heapq这个库完美地解决了top-K问题。
Python heapq模块常用函数复习:
1.heapq.heappush(heap, item) 把item添加到heap中(heap是一个列表)
2.heapq.heappop(heap) 把堆顶元素弹出,返回的就是堆顶
3.heapq.heappushpop(heap, item) 先把item加入到堆中,然后再pop,比 heappush()heappop() 要快得多
4.heapq.heapreplace(heap, item) 先pop,然后再把item加入到堆中,比 heappop()heappush() 要快得多
5.heapq.heapify(x)列表x进行堆调整,默认的是小顶堆
6.heapq.merge(*iterables) 将多个列表合并,并进行堆调整,返回的是合并后的列表的迭代器
7.heapq.nlargest(n, iterable, key=None) 返回最大的n个元素,是个列表 list,从大到小排序(Top-K问题)
8.heapq.nsmallest(n, iterable, key=None)返回最小的n个元素,是个列表 list,从小到大排序(Top-K问题)

c++的heap不好用,不说了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值