HeapSelect求解方法
使用这种方法求解,需要借助一种数据结构叫做堆。这里我们使用的是小根堆。
- 首先把数组中的前k个值用来建一个小根堆。
- 之后的其他数拿到之后进行判断,如果遇到比小顶堆的堆顶的值大的,将它放入堆中
- 最终的堆会是数组中最大的K个数组成的结构,小根堆的顶部又是结构中的最小数,因此把堆顶的值弹出即可得到Top-K。
public class TopKHeapSelect {
public int findKthLargest(int[] num, int k) {
if (num.length < k) return 0;
Queue<Integer> minQueue = new PriorityQueue<>(k + 1);
for (int n : num) {
if (minQueue.size() < k || n > minQueue.peek()) minQueue.offer(n);
if (minQueue.size() > k) minQueue.poll();
}
return minQueue.peek();
}
}
QuickSelect求解方法
1.运用快排的思想,将数组进行一次partition过程之后就可以得到两部分,求出第一部分长度,根据长度和k的关系,来选择递归的继续去转这个partition,知道长度和k相同,也就是得到了第Top-k的数。这个算法的时间复杂度在长期期望下是O(n)的,但是在最坏情况下是O(n^2)的一个算法。
import java.util.Random;
public class TopKQuickSelect {
public int findKthLargest(int[] nums, int k) {
if (nums == null || k < 0) return Integer.MAX_VALUE;
int length = nums.length;
return quickSelect(nums, k, 0, length - 1);
}
/**
* 根据快排思想得到的Quickselect算法
* @param nums
* @param k
* @param start
* @param end
* @return
*/
private int quickSelect(int[] nums, int k, int start, int end) {
Random random = new Random();
int index = random.nextInt(end - start &#