0
点赞
收藏
分享

微信扫一扫

一刷180-力扣热题-215数组中的第K个最大元素(m)

芷兮离离 2022-03-12 阅读 85
题目:
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
 
提示:
1 <= k <= nums.length <= 104
-104 <= nums[i] <= 104
-----------------
思考:
题目要求我们找到「数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素」。
「数组排序后的第 k 个最大的元素」换句话说:从右边往左边数第 k 个元素(从 1 开始),
那么从左向右数是第几个呢,我们列出几个找找规律就好了。

一共 6个元素,找第 2 大,下标是 4;
一共 6个元素,找第 4 大,下标是 2。
因此升序排序以后,目标元素的下标是 N - k,这里 N 是输入数组的长度。

优先队列
优先队列的思路是很朴素的。
由于找第 K 大元素,其实就是整个数组排序以后后半部分最小的那个元素。
因此,我们可以维护一个有 K 个元素的最小堆:

如果当前堆不满,直接添加;
堆满的时候,如果新读到的数小于等于堆顶,肯定不是我们要找的元素,
只有新遍历到的数大于堆顶的时候,才将堆顶拿出,然后放入新读到的数,进而让堆自己去调整内部结构。
说明:这里最合适的操作其实是 replace(),
即直接把新读进来的元素放在堆顶,然后执行下沉(siftDown())操作。
Java 当中的 PriorityQueue 没有提供这个操作,只好先 poll()offer()。

复杂度分析:
时间复杂度:O(NlogK),遍历数据O(N),堆内元素调整O(logK);
空间复杂度:O(K)
class Solution {
    public int findKthLargest(int[] nums, int k) {
        //创建队列 确定大小为K
        PriorityQueue<Integer> queue = new PriorityQueue<>(k, Comparator.comparingInt(a -> a));//!  Comparator 大写
        for (int i = 0; i < k; i++) {//先将前K个元素添加入栈
            queue.offer(nums[i]);
        }
        for (int i = k; i < nums.length; i++) {
            int top = queue.peek();
            if (nums[i] > top) {
                queue.poll();
                queue.offer(nums[i]);
            }
        }
        return queue.peek();
    }
}

LC

举报

相关推荐

0 条评论