您的位置:首页 > 其它

LeetCode 215 Kth Largest Element in an Array

2016-07-22 01:34 351 查看
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.
思路:

选取数组合适的element作为pivot
 (提高效率)
使用partition,elements<=pivot的放到pivot前,elements>=pivot的elements放到pivot后,pivot就放到了正确位置position。
缩小下次partition查找的范围。如果pivot的position比target大,那么扔掉pivot之后的elements,继续在pivot之前的elements里面找。反之,pivot的position小于target,扔掉pivot之前的elements,再pivot之后的elements里继续partition。这样不断缩小,一直到不能再缩小。
nums[target] 就是 the kth distinct element。

1ms
Java solution beats 99.1%.

public int findKthLargest(int[] nums, int k) {
int n = nums.length, target = n - k;
quicksort(nums, 0, n - 1, target);
return nums[n - k]; //nums[n - k]就是the kth largest element
}

private void quicksort(int[] nums, int start, int end, int target) {
if (start >= end) return;
int mid = start + (end - start) / 2;
int pivot = choosePivot(nums[mid], nums[start], nums[end]);
int i = start, j = end;
while (i <= j) {
while (nums[i] < pivot) i++;
while (nums[j] > pivot) j--;
if (i <= j) {
if (nums[i] != nums[j]) swap(nums, i, j);
i++;
j--;
}
}
if (target <= i - 1) quicksort(nums, start, i - 1, target);
else quicksort(nums, i, end, target);
}

/**选取a,b,c三者的中位数*/
private int choosePivot(int a, int b, int c) {
int min = Math.min(a, Math.min(b, c));
int max = Math.max(a, Math.max(b, c));
return a - max + b - min + c;
}

private void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
思路:
使用优先队列,维护size为k的小顶堆,堆顶的元素就是第k大的元素,而其余元素都比这个元素大。
9ms Java solution
beats 66.46%.

public int findKthLargest2(int[] nums, int k) {
PriorityQueue<Integer> pq = new PriorityQueue<Integer>(k);
for (int i = 0; i < nums.length; i++) {
if (pq.size() < k) pq.offer(nums[i]);
else if (nums[i] > pq.peek()) {
pq.poll();
pq.offer(nums[i]);
}
}
return pq.peek();
}
总结:一般快排的话,选取pivot的时候,不能每次只选第一个或者最后一个,可以选第一个或中间的或最后一个,最好选三者中排名第二大的;或者选取pivot之前,将无序数组进行shuffle也是不错的办法,但是效果还是前者更好。

参考https://discuss.leetcode.com/topic/51286/my-1ms-java-solution-beats-100
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode