summary:
approach 1 : divide and conquer | use the idea of quick sort | O(N) avg.
approach 2 : min heap filter the data | O(NlogK)
package com.odyssey.app.algorithm.lc.divideandconquer;
import java.util.PriorityQueue;
/**
*
* @author Dingsheng Huang
* @date 2020/3/13 21:41
*
* 215
* medium
* https://leetcode.com/problems/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.
*
*/
public class KthLargestElementInAnArray {
// approach 1 : divide and conquer , use the idea of quick sort , O(n)
public int findKthLargest(int[] nums, int k) {
if (nums.length == 0) {
return -1;
}
if (nums.length == 1) {
return nums[0];
}
return partition(nums, 0, nums.length - 1, k);
}
private int partition(int[] nums, int lo, int hi, int k) {
// corner case
if (lo == hi) {
return nums[hi];
}
int target = nums[lo];
int i = lo;
int j = hi + 1;
while (true) {
while (nums[++i] < target) {
if (i == hi) {
break;
}
}
while (nums[--j] > target) {
if (j == lo) {
break;
}
}
if (i >= j) {
break;
}
exch(nums, i, j);
}
exch(nums, lo, j);
int count = hi + 1 - j;
if (count == k) {
return nums[j];
}
if (count > k) {
return partition(nums, j + 1, hi, k);
}
return partition(nums, lo, j - 1, k - count);
}
private void exch(int[] arr, int x, int y) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
// approach 2 : use min heap filter data
public int findKthLargest2(int[] nums, int k) {
PriorityQueue<Integer> minHeap = new PriorityQueue<>(k);
for (Integer item : nums) {
if (minHeap.size() < k) {
minHeap.add(item);
continue;
}
if (item > minHeap.peek()) {
minHeap.remove();
minHeap.add(item);
}
}
return minHeap.peek();
}
}