堆排序 leetcode 力扣 215 数组中的第k个最大元素

79 阅读1分钟

堆排序感觉要比快排好理解一点,但是有些边界条件还是要注意

比如,在建完大根堆后,需要依次删除堆顶元素。

i > nums.length - k:寻找倒数第k个元素,只需要删除k - 1次堆顶元素,然后返回堆顶元素即可。

for (int i = heapSzie - 1; i > nums.length - k; i--) {
            swap(nums, 0, i);
            heapSzie--;
            maxHeapify(nums, 0, heapSzie);
}

1.jpeg

2.jpeg

3.jpeg

4.jpeg

5.jpeg

6.jpeg

7.jpeg

8.jpeg

开始寻找倒数第k个元素 9.jpeg

10.jpeg

11.jpeg

12.jpeg

13.jpeg

class Solution {
    public int findKthLargest(int[] nums, int k) {
        int heapSzie = nums.length;
        buildMaxHeap(nums, heapSzie);

        for (int i = heapSzie - 1; i >= nums.length - k + 1; i--) {
            swap(nums, 0, i);
            heapSzie--;
            maxHeapify(nums, 0, heapSzie);
        }

        return nums[0];
    }

    public void buildMaxHeap(int[] nums, int heapSzie) {
        for (int i = heapSzie / 2 - 1; i >= 0; i--) {
            maxHeapify(nums, i, heapSzie);
        }
    }

    public void maxHeapify(int[] nums, int i, int heapSzie) {
        int left = i * 2 + 1;
        int right = i * 2 + 2;
        int largest = i;

        if (left < heapSzie && nums[left] > nums[largest]) {
            largest = left;
        }

        if (right < heapSzie && nums[right] > nums[largest]) {
            largest = right;
        }

        if (largest != i) {
            swap(nums, i, largest);
            maxHeapify(nums, largest, heapSzie);
        }
    }

    public void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}