[leetcode]215. 数组中的第K个最大元素

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 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

说明:

你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

方法一:
利用优先队列(priority_queue)实现小根堆;向小根堆中依次添加元素,每次添加之后如果小根堆的容量超过k,则删除堆顶元素,即堆中最小的元素。

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int, vector<int>, greater<int>> minHeap;
        
        for (int i = 0; i < nums.size(); i++) {
            minHeap.push(nums[i]);
            if (minHeap.size() > k)
                minHeap.pop();
        }
        return minHeap.top();
    }
};

方法二:
利用优先队列(priority_queue)实现大根堆;然后从堆中依次删除k-1个堆顶元素,返回测试的堆顶元素即可;

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int, vector<int>, less<int>> heap;
        
        for (int i = 0; i < nums.size(); i++)
            heap.push(nums[i]);
        for (int i = 0; i < k-1; i++)
            heap.pop();
        return heap.top();
    }
};

方法三:
利用快速排序思想,对数组进行划分,并且判断划分的边界元素位置mid是否为第k大的数(k - 1); 若是则返回该数,若mid > k - 1说明第k大的数在左半边数组里;若mid < k - 1说明在右半边数组里。对其继续进行数组划分,直到找到第k大的数。 数组划分函数partation采用当前部分数组位置的最后一个元素值作为pivot(轴),也可以采用随机元素,最好不要用第一个(最后一个)元素,防止数组绝大部分元素是有序的,影响查找效率。

作者:liushang-leecode
链接:https://leetcode-cn.com/problems/two-sum/solution/kuai-su-pai-xu-si-xiang-shu-zu-hua-fen-by-liushang/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class Solution {
    int partition(int low, int high, vector<int>& nums) {
        int left = low;
        int right = high;
        int mid = (left + right) / 2;
        swap(nums[mid], nums[right]);
        int pivot = nums[high];
        while (left < right) {
            while (left < right && pivot < nums[left]) left++;
            while (left < right && pivot >= nums[right]) right--;        
            if (left < right)
                swap(nums[right], nums[left]);
        }
        swap(nums[left], nums[high]);
        nums[left] = pivot;
        return left;
    }
public:
    int findKthLargest(vector<int>& nums, int k) {
        int low = 0;
        int high = nums.size() - 1;
        if (high == 0)
            return nums[0];
        while (low <= high) {
            int mid = partition(low, high, nums);
            if (mid == k-1)
                return nums[mid];
            else if (mid > k-1)
                high = mid - 1;
            else 
                low = mid + 1;
        }
        return -1; 
    }
    
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值