215. Kth Largest Element in an Array

本文介绍了一种高效的方法来查找数组中第k大的元素,包括排序、建堆和优先队列等策略,每种方法都有其时间和空间复杂度分析。

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.

For example,
Given [3,2,1,5,6,4] and k = 2, return 5.

Note: 

You may assume k is always valid, 1 ≤ k ≤ array's length.

题意:找到数组中第k大的值。

思路:1. 先排序,然后返回第k大的值即可,复杂度O(nlgn)。beats 55%

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        sort(nums.begin(), nums.end(), greater<int>());
        return nums[k-1];
    }
};
思路2: 对数组A[1..n]第k-n间的元素进行建堆,然后依次拿剩余的k-1个元素与大顶堆的堆顶进行比较,若大于堆顶则不处理,若小于堆顶,则将该值与堆顶的值置换(并调平衡堆顶),然后剩余的值继续跟堆顶值比较,最后返回堆顶的值,即为第k大的值。复杂度 max{ O(n+1-k),  O(klg(n+1-k)) }。

beats 88.37%

class Solution {
public:
	int findKthLargest(vector<int>& nums, int k) {
		int heap_size = nums.size() + 1 - k;
		build_max_heap(nums, heap_size);
		for (int i = heap_size; i < nums.size(); i++){
			if (nums[i] < nums[0]){
				swap(nums[i], nums[0]);
				max_heapify(nums, 0, heap_size);
			}
		}
		return nums[0];
	}

	void build_max_heap(vector<int>& a, int heap_size){
		for (int i = heap_size / 2 - 1; i >= 0; i--)
			max_heapify(a, i, heap_size);
	}

	void max_heapify(vector<int>& a, int i, int heap_size){
		int largest = i;
		int left = 2 * i + 1;
		int right = 2 * i + 2;
		if (left < heap_size && a[left] > a[i])
			largest = left;

		if (right < heap_size && a[right] > a[largest])
			largest = right;

		if (largest != i){
			int tmp = a[i];
			a[i] = a[largest];
			a[largest] = tmp;
			max_heapify(a, largest, heap_size);
		}
	}

};

思路3:借助优先队列实现上述过程,先把n+1-k个元素放入优先队列,然后依次比较优先队列的top值和剩余的k-1个值并做交换。beats 73.75%

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

思路4:数据全部放优先队列里,然后依次吐出k-1次。复杂度O(n) 或O(klgn) beats 50.70%

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

思路5:使用nth_element()。 beats: 88.37%

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];
	}
};







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值