LeetCode215. Kth Largest Element in an Array

本文介绍在未排序数组中查找第K大元素的多种高效算法,包括使用排序、快速选择、堆和STL函数的方法。通过实例展示每种算法的实现过程,帮助读者理解并掌握这些算法。

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

Kth Largest Element in an Array

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 assume k is always valid, 1 ≤ k ≤ array’s length.

1. std::sort(),reverse().O(nlogn)

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        sort(nums.begin(),nums.end());
        reverse(nums.begin(),nums.end());
        return nums[k-1]; 
    }
};

2.Partition.O(n)

#include <vector>
using namespace std;

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) 
    {
        if(nums.empty()||k>nums.size())
        return 0;

        k=nums.size()-k;//从小到大排列后的k
        QuickSort_Recur(nums,0,nums.size()-1);
 
        return nums[k];
    }
     void QuickSort_Recur(vector<int>& nums, int low, int high)
    { 
        if(low<high)
        {
            int index = Partition(nums,low,high);//找到一个基准,并将所有小于基准的数放在基准左边。
            QuickSort_Recur(nums,low,index-1);
            QuickSort_Recur(nums,index+1,high);
        }
    }

    int Partition(vector<int>& nums,int start,int end)
    {
        if(start<0||end>=nums.size())
          return 0;

        int pivot = random(start,end);
        swap(&nums[pivot],&nums[end]);//把基准移到尾部
        
        int left = start -1;//最左边原地划分一个子集
        for(int i =start;i<end;i++)
        {
            if(nums[i]<nums[end])//如果小于基准就放入子集中
            {
                left++;
                if(left!=i)
                    swap(&nums[i],&nums[left]);
            }
        }

        left++;
        swap(&nums[left],&nums[end]);//将最尾部的基准放在左子集的下一个位置

        return left;//返回基准
     }
    int random(int min,int max)
    {
        int random =rand()%(max-min+1) +min;
        return random;
    }
    void swap(int *in1,int* in2){
        int temp=*in1;
        *in1=*in2;
        *in2=temp;
    }
};

3.heap. STL的Priority queue

max-heap:将N个元素塞入一个最大堆,将堆顶元素删除k-1次。堆顶就是要找的第K大的元素。
min-heap:将K个最大元素塞入一个最小堆。堆顶就是要找的第K大的元素。
在STL中。priority_queuemultiset可以实现最大堆/最小堆。

using priority_queue

min-heap

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int, vector<int>, greater<int>> pq;
        for (int num : nums) {
            pq.push(num);
            if (pq.size() > k) {
                pq.pop();
            }
        }
        return pq.top();
    }
};

max-heap

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int> pq(nums.begin(), nums.end());
        for (int i = 0; i < k - 1; i++) {
            pq.pop();
        }
        return pq.top();
    }
};

using multiset(rbt)

min-heap

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        multiset<int> mset;
        for (int num : nums) {
            mset.insert(num);
            if (mset.size() > k) {
                mset.erase(mset.begin());
            }
        }
        return *mset.begin();
    }
};

max-heap

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        multiset<int, greater<int>> mset(nums.begin(), nums.end());
        for (int i = 0; i < k - 1; i++) {
            mset.erase(mset.begin());
        }
        return *mset.begin();
    }
};

4.STL的nth_element和partial_sort

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        nth_element(nums.begin(), nums.begin() + k - 1, nums.end(), greater<int>());
        return nums[k - 1];
    }
};
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        partial_sort(nums.begin(), nums.begin() + k, nums.end(), greater<int>());
        return nums[k - 1];
    }
};

请注意两个内置函数的第二个参数中的1之差。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值