利用数组 a 的前k个元素,建立 k 个元素的小根堆,然后遍历剩余的n-k的数,依次跟堆顶元素比较,如果比堆顶元素小,则放弃,如果比堆顶元素大,则加入堆并调整。遍历完成后,返回堆顶元素,即为第K大的数。

import java.util.*;

public class Solution {
    public int findKth(int[] a, int n, int K) {
        // write code here
        // 利用数组 a 建立 k 个元素的小根堆,然后遍历剩余的n-k的数,依次跟堆顶元素比较
        // 如果比堆顶元素小,则放弃,如果比堆顶元素大,则加入堆并调整
        // 遍历完成后,返回堆顶元素
        initHeap(a, K);
        for(int i = K; i < n; i++) {
            addToHeap(a, i, K);
        }
        return a[0];
    }
    private void addToHeap(int[] a, int idx, int k){
        if(a[0] > a[idx]) {
            return;
        }
        a[0] = a[idx];
        adjust(a, 0, k);
    }
    
    private void initHeap(int[] a, int k) {
        int l = (k - 2) / 2;
        for (int i = k - 1; i >= l; i--) {
            int child = i;
            while(child != 0) {
                int parent = (child - 1) / 2;
                if(a[child] < a[parent]) {
                    swap(a, child, parent);
                    adjust(a, child, k);
                }
                child = parent;
            }
            
        }
    }
    
    private void swap(int[] a, int i, int j) {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    
    private void adjust(int[] a, int start, int k) {
        while(true) {
            int minIdx = 2 * start + 1; 
            if (minIdx >= k) {
               break;
            }
            int right = 2 * start + 2; 
            if (right < k) {
                minIdx = a[minIdx] < a[right] ? minIdx:right;
            }
            if(a[start] > a[minIdx]) {
                swap(a, start, minIdx);
                start = minIdx;
            } else {
                break;
            }
        }
    }
}