LeetCode215_数组中的第K个最大元素_排序_堆排序_非递归写法

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;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值