一、题目内容

image.png

二、题解

解法1:小顶堆

思路

堆。
PriorityQueue 默认为小顶堆,实现Comparator可以改为大顶堆。

代码

  1. int[] ans = new int[k];
  2. if (k == 0) {
  3. return ans;
  4. }
  5. PriorityQueue<Integer> queue = new PriorityQueue<Integer>(new Comparator<Integer>() {
  6. @Override
  7. public int compare(Integer o1, Integer o2) {
  8. //大顶
  9. return o2 - o1;
  10. }
  11. });
  12. //先填满
  13. for (int i = 0; i < k; i++) {
  14. queue.add(arr[i]);
  15. }
  16. for (int i = k; i < arr.length; i++) {
  17. if (queue.isEmpty()) {
  18. queue.add(arr[i]);
  19. } else {
  20. if (queue.peek() > arr[i]) {
  21. queue.poll();
  22. queue.add(arr[i]);
  23. }
  24. }
  25. }
  26. for (int i = 0; i < k; i++) {
  27. ans[i] = queue.poll();
  28. }
  29. return ans;

解法2:大顶堆,自己实现

思路

用大顶堆,自己实现一个堆

代码

public int[] getLeastNumbers(int[] arr, int k) {
    if (arr == null || k == 0) {
        return new int[0];
    }
    int[] maxHeapArr = new int[k];
    int i;
    for (i = 0; i < k; i++) {
        maxHeapArr[i] = arr[i];
    }

    buildMaxHeap(maxHeapArr);
    while (i < arr.length) {
        if (arr[i] < maxHeapArr[0]) {
            maxHeapArr[0] = arr[i];
            adjustMaxHeap(maxHeapArr, 0);
        }
        i++;
    }

    return maxHeapArr;
}

public void buildMaxHeap(int[] a) {
    for (int i = a.length / 2 - 1; i >= 0; i--) {
        adjustMaxHeap(a, i);
    }
}

public void adjustMaxHeap(int[] a, int currPos) {
    int len = a.length;

    int tempRoot = a[currPos];
    //从当前节点的左子节点开始
    for (int k = currPos * 2 + 1; k < len; k = 2 * k + 1) {
        //如果左子节点小于右子节点,则右移一位,然后比较最大的子节点与当前的跟大小,小于当前跟则替换,使其满足大顶堆条件
        if (k + 1 < len && a[k] < a[k + 1]) {
            k++;
        }
        if (a[k] > tempRoot) {
            a[currPos] = a[k];
            currPos = k;
        } else {
            break;
        }
    }
    a[currPos] = tempRoot;
}