LeetCode 215 – 数组中的第K个最大元素

题目描述

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

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

题目分析

优先队列

遍历数组,放入小顶优先队列,超出 k 个时取出1个顶部元素。
最终顶部元素即为第K个最大元素。
时间复杂度 O(n * logk)

哈希计数

遍历一边数组,使用哈希表记录每个数字出现的次数,同时找出最大值和最小值。
从最大值开始对次数求和,sum >= k 时退出。
时间复杂度 O(n)

快速选择

快排的过程中判断 k 落在哪个区间,然后递归.
每层平均减少一半元素,处理次数为 n + n/2 + n/4 … + n/x <= 2n
时间复杂度 O(n)

Java

public int findKthLargest(int[] nums, int k) {
    PriorityQueue<Integer> queue = new PriorityQueue<>();
    for (int x : nums) {
        queue.offer(x);
        if (queue.size() > k) {
            queue.poll();
        }
    }
    return queue.poll();
}

Kotlin

// 优先队列
fun findKthLargest(nums: IntArray, k: Int): Int {
    val queue = PriorityQueue<Int>()
    for (n in nums) {
        queue.offer(n)
        if (queue.size > k) {
            queue.poll()
        }
    }
    return queue.poll()
}

// 哈希表计数
fun findKthLargest2(nums: IntArray, k: Int): Int {
    var min = nums.first()
    var max = nums.first()
    val count = HashMap<Int, Int>()
    for (n in nums) {
        count[n] = (count[n] ?: 0) + 1
        min = min(min, n)
        max = max(max, n)
    }
    var sum = 0
    for (n in max downTo min) {
        sum += count[n] ?: 0
        if (sum >= k) {
            return n
        }
    }
    return 0
}


// 快速选择
fun findKthLargest(nums: IntArray, k: Int, start: Int = 0, end: Int = nums.size - 1): Int {
    val target = nums[end]
    var index = start
    for (i in start..end) {
        if (nums[i] > target) {
            swap(nums, i, index++)
        }
    }
    swap(nums, end, index)
    val count = index - start // 左侧数量

    return if (count < k - 1) {
        findKthLargest(nums, k - count - 1, index + 1, end)
    } else if (count > k - 1) {
        findKthLargest(nums, k, start, index - 1)
    } else {
        nums[index]
    }
}

private fun swap(nums: IntArray, i: Int, j: Int) {
    val temp = nums[i]
    nums[i] = nums[j]
    nums[j] = temp
}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部