B站视频讲解【LeetCode215_数组中的第K个最大元素_排序_堆排序_非递归写法】 LeetCode215_数组中的第K个最大元素_排序_堆排序_非递归写法
class Solution {
public int findKthLargest(int[] nums, int k) {
// 使用堆排序
// 初始化大顶堆
// 输出k - 1次堆顶元素,调整剩余元素为新的大顶堆,堆顶即为所求值
return heapSort(nums, k);
}
public int heapSort(int[] nums, int k) {
// 初始化大顶堆
bulidMaxHeap(nums);
// 输出k - 1次堆顶元素,调整剩余元素为新的大顶堆,堆顶即为所求值
int len = nums.length;
for (int i = nums.length - 1; i > nums.length - k; i--) {
// 输出k - 1次堆顶元素
// 交换堆顶元素与堆底元素,即堆顶元素找到了最终位置
swap(nums, 0, i);
// 调整剩余元素为新的大顶堆
len--;
heapAdjust(nums, 0, len);
}
// 堆顶即为所求值
return nums[0];
}
public void bulidMaxHeap(int[] nums) {
int length = nums.length;
// length / 2 - 1是最后一个子树的根节点的索引
for (int i = length / 2 - 1; i >= 0; i--) {
// 自下向上对堆进行调整
heapAdjust(nums, i, length);
}
}
public void heapAdjust(int[] nums, int root, int heapLen) {
// 临时存放子树根节点的值,在找到子树根节点的最终索引时,将子树根节点的值赋给子树根节点的最终索引
int temp = nums[root];
// (root << 1) + 1代表子树根节点的左孩子节点
for (int i = (root << 1) + 1; i < heapLen; i = (i << 1) + 1) {
// 该判断保证了子树根节点与孩子节点中的最大值进行比较
if (i < heapLen - 1 && nums[i] < nums[i + 1]) {
i++;
}
if (temp >= nums[i]) {
break;
}
// 把孩子节点中的最大值赋给子树根节点
nums[root] = nums[i];
// 迭代地找到子树根节点的最终索引
root = i;
}
// 将子树根节点的值赋给子树根节点的最终索引
nums[root] = temp;
}
public void swap(int[] nums, int a, int b) {
if (nums[a] != nums[b]) {
int temp = nums[a];
nums[a] = nums[b];
nums[b]= temp;
}
}
}