LeeCode 215. 数组中的第K个最大元素

题目:

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

  • 示例 1:
    输入: [3,2,1,5,6,4] 和 k = 2
    输出: 5

  • 示例 2:
    输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
    输出: 4
    说明:
    你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:

1.暴力法起步:

直接给数组排序,时间复杂度O(n*logn),Arrays.sort是按照从小到大的顺序排序。
要求第K大的元素,那么就返回下标为 len - k 的元素就行了
比如 第4大的元素,数组一共6个元素
第4大就是从前往后的第2个 2 = 6 - 4
比如 第2大的元素,数组一共6个元素
第2大就是从前往后的第4个 2 = 6 - 4
So :

//sort   算是暴力办法
    public static int findKthLargest(int[] nums, int k) {
        if(nums == null || nums.length == 0)
            return 0;
        Arrays.sort(nums);
        int len = nums.length;
        return nums[len - k];
    }

这是个中等的题,第一下用暴力法做出来的时候都惊呆了,就这么点?
事实证明,该暴力法还比较快,只用了2ms

2.堆

但是肯定没有这么简单,既然是中等题就该有中等题的样子
想了下别的算法,这个时候就涉及到了堆这个数据结构。
维基百科:链接.

给定堆中任意节点P和C,若P是C的母节点,那么P的值会小于等于(或大于等于)C的值”。
若母节点的值恒小于等于子节点的值,此堆称为最小堆(min heap);
反之,若母节点的值恒大于等于子节点的值,此堆称为最大堆(max heap)

那么我们是否可以维护一个最小堆 堆的堆顶节点是最小值,如果堆一直维持在k个元素,那么堆顶就是第K大的元素。
通过for循环,每次往最大堆中加入数组的元素,

  • 当最大堆的size < k的时候,只管add
  • 当size == k的时候,先add元素,堆会自动将最大的值放到堆顶(堆自动维护堆的性质),然后再移除该堆顶节点
    最后的时候,返回堆顶节点即可。
代码1:
//最小堆
    public static int findKthLargestDemo(int[] nums, int k) {
        if(nums == null || nums.length == 0)
            return 0;
        PriorityQueue<Integer> heap = new PriorityQueue<>(nums.length, (n1,n2) -> n1 - n2);
        for(int i : nums) {
            heap.add(i);
            if(heap.size() > k)
                heap.poll();
        }
        return heap.peek();
    }

当然,也可以把堆的数量直接限制在K个

代码2:
//k 个元素的最小堆
    public int findKthLargestDemo2(int[] nums, int k) {
        int len = nums.length;
        // 使用一个含有 k 个元素的最小堆
        PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, (a, b) -> a - b);
        for (int i = 0; i < k; i++) {
            minHeap.add(nums[i]);
        }
        for (int i = k; i < len; i++) {
            //获取堆顶节点的值
            Integer top = minHeap.peek();
            //如果当前遍历的数组元素大于堆顶节点,堆顶弹出,遍历的元素进去
            if (nums[i] > top) {
                minHeap.poll();
                minHeap.add(nums[i]);
            }
        }
        return minHeap.peek();
    }

堆的知识还有一堆 ,比如堆排序,如何自己实现一个堆,堆的增删查的底层如何实现,
果然,中等题还是有中等题的原因,学起来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值