LCR 076. 数组中的第 K 个最大元素(快排+堆排序)

1.快速排序

class Solution {
    int k;
    int ans = -1;

    public int findKthLargest(int[] nums, int _k) {
        k = _k;
        quicksort(nums, 0, nums.length - 1);
        return ans;
    }

    void quicksort(int[] nums, int l, int r) {
        // 到达边界
        if (l >= r) {
            // 记得判断是不是我们要找的数字
            if (l == nums.length - k) ans = nums[l];
            return;
        }
        int i = l, j = r;
        while (i < j) {
            // 从后向前找比基准小的数字
            while (i < j && nums[j] >= nums[l]) j--;
            // 从前向后找比基准大的数字
            while (i < j && nums[i] <= nums[l]) i++;
            // 交换位置
            swap(nums, i, j);
        }
        // 全部交换完毕后 更新基准数字的位置
        swap(nums, i, l);
        // 判断是否找到第k大数字
        if (i == nums.length - k) {
            ans = nums[i];
            return;
        }
        // 继续递归
        quicksort(nums, l, i - 1);
        quicksort(nums, i + 1, r);
    }

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

2.堆排序

class Solution {
    public int findKthLargest(int[] nums, int k) {
        int n = nums.length;
        // 构造一个大顶堆
        buildHeap(nums, n);
        for (int i = 1; i < k; i++) {
            // 弹出堆顶元素
            swap(nums, 0, n - 1);
            // 重新堆化
            heapify(nums, 0, --n);
        }
        return nums[0];
    }

    void buildHeap(int[] nums, int n) {
        // 从最底层的父节点开始构建大顶堆 n 是数组长度 注意减一优化
        for (int i = (n - 1) / 2; i >= 0; i--) {
            heapify(nums, i, n);
        }
    }

    void heapify(int[] nums, int i, int n) {
        int maxPos = i;
        while (true) {
            // 在左右子节点中找更大值
            if (i * 2 + 1 < n && nums[i * 2 + 1] > nums[maxPos]) {
                maxPos = i * 2 + 1;
            }
            if (i * 2 + 2 < n && nums[i * 2 + 2] > nums[maxPos]) {
                maxPos = i * 2 + 2;
            }
            // 下标不变说明堆已经是大顶堆了
            if (i == maxPos) break;
            // 否则更新当前位置的最大值
            swap(nums, i, maxPos);
            // 继续向下维护大顶堆
            i = maxPos;
        }
    }

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值