以215. 数组中的第K个最大元素 - 力扣(LeetCode)为例
用Java已有的大顶堆来解决,耗时如下

而如果手撕出来堆,结果则:

原因即:
PriorityQueue 是基于包装类 Integer、自动装箱、JDK 自带堆(底层数组 + 额外对象开销)
手写原地大顶堆,直接在原始 int 数组上操作,没有装箱拆箱、没有额外对象 ,所以快很多
具体代码如下:
java
//Java已有堆
class Solution {
public int findKthLargest(int[] nums, int k) {
int len = nums.length;
PriorityQueue<Integer> bigHeap = new PriorityQueue<Integer>(new Comparator<Integer>(){
@Override
public int compare(Integer num1,Integer num2){
return num2 - num1;
}
});
for(int i = 0 ; i < len ; i ++){
bigHeap.offer(nums[i]);
}
for(int i = 0 ; i < k - 1 ; i ++){
bigHeap.poll();
}
return bigHeap.peek();
}
}
java
//纯手撕
class Solution {
public int findKthLargest(int[] nums, int k) {
int heapSize = nums.length;
buildMaxHeap(nums,heapSize);
for(int i = nums.length - 1;i >= nums.length - k + 1; i --){
swap(nums,0,i);
heapSize --;
maxHeapify(nums,0,heapSize);
}
return nums[0];
}
public void buildMaxHeap(int[] a,int heapSize){
for(int i = heapSize / 2 -1 ; i >= 0 ; i --){
maxHeapify(a,i,heapSize);
}
}
public void maxHeapify(int[] a, int i, int heapSize){
int l = i * 2 + 1;
int r = i * 2 + 2;
int largest = i;
if(l < heapSize && a[l] > a[largest]){
largest = l;
}
if(r < heapSize && a[r] > a[largest]){
largest = r;
}
if(largest != i){
swap(a,i,largest);
maxHeapify(a,largest,heapSize);
}
}
public void swap(int[] a,int i ,int j){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}