这个题目反正我是只通过了九个测试用了,而且感觉自己的好像还挺对的。但是最后那个很长的就是通不过,说一说思路吧。这个题目一看就能看出来,使用小根堆。代码如下:
class KthLargest {
//维持一个大小为k的最小堆
int[] heap;
public KthLargest(int k, int[] nums) {
heap = new int[k+1]; //堆的第一个位置不存元素
int nLength = nums.length;
for(int i = 1; i <= k; ++i) { //先把前k个元素加入到堆中,如果没有了则加入MIN
if (i > nums.length)
heap[i] = Integer.MIN_VALUE;
else heap[i] = nums[i-1];
}
for (int i = 1; i <= k; ++i) { //对堆中的元素进行调整,加入MIN就是保证调整的进行
siftDown(heap, i, heap[i]);
}
for (int i = k; i < nLength; ++i) { //将num中剩下的元素加入到堆中
add(nums[i]);
}
}
private void siftDown(int[] heap, int i, int ele) {
int child = i*2, parent = i; //找到当前的根和孩子
while(child < heap.length) { //小根堆调整,需要找较小的元素提上去
if (child + 1 < heap.length && heap[child+1] < heap[child]) {
child++;
}
if (ele > heap[child]) { //如果当前元素比较小的孩子大,则把孩子提上去,继续遍历
heap[parent] = heap[child];
parent = child;
child = parent * 2;
} else { //否则比两个孩子都小,则不用继续调整了
break;
}
}
heap[parent] = ele; //将元素放到目标位置
}
public int add(int val) {
if (val < heap[1]) //如果是个更小的元素,则抛弃
return heap[1];
heap[1] = val; //否则把小的堆顶去掉,然后调整
siftDown(heap, 1, val);
return heap[1]; //返回堆顶
}
}