Kth Largest Element in an Array

Question

Find K-th largest element in an array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

Notice

You can swap elements in the array

Example

In array [9,3,2,4,8], the 3rd largest element is 4.

In array [1,2,3,4,5], the 1st largest element is 5, 2nd largest element is 4, 3rd largest element is 3 and etc.

Challenge

O(n) time, O(1) extra memory.

Analysis

Sort Array

  • O(nlogn) time

Max Heap

  • O(nlogk) running time + O(k) memory

在数字集合中寻找第k大,可以考虑用Max Heap,将数组遍历一遍,加入到一个容量为k的PriorityQueue,最后poll() k-1次,那么最后剩下在堆顶的就是kth largest的数字了。

另外此题用quick sort中的 quick select 的思路来解,更优化,参考:http://www.jiuzhang.com/solutions/kth-largest-element/

Quick Select

  • Time Complexity: average = O(n); worst case O(n^2), O(1) space

注意事项:

  • partition的主要思想:将比pivot小的元素放到pivot左边,比pivot大的放到pivot右边

  • pivot的选取决定了partition所得结果的效率,可以选择left pointer,更好的选择是在left和right范围内随机生成一个;

Time Complexity O(n)来自于O(n) + O(n/2) + O(n/4) + ... ~ O(2n),此时每次partition的pivot大约将区间对半分。

Source: https://discuss.leetcode.com/topic/15256/4-c-solutions-using-partition-max-heap-priority_queue-and-multiset-respectively

So, in the average sense, the problem is reduced to approximately half of its original size, giving the recursion T(n) = T(n/2) + O(n) in which O(n) is the time for partition. This recursion, once solved, gives T(n) = O(n) and thus we have a linear time solution. Note that since we only need to consider one half of the array, the time complexity is O(n). If we need to consider both the two halves of the array, like quicksort, then the recursion will be T(n) = 2T(n/2) + O(n) and the complexity will be O(nlogn).

Of course, O(n) is the average time complexity. In the worst case, the recursion may become T(n) = T(n - 1) + O(n) and the complexity will be O(n^2).

Solution

Sort Array

O(nlogn)

Max Heap

O(N lg K) running time + O(K) memory

Min Heap

O(N lg K) running time + O(K) memory

Quick Select: O(N) best case / O(N^2) worst case running time + O(1) memory

Use Shuffle : O(N) guaranteed running time + O(1) space

Quick Select (Partition with two pointers)

O(N) best case / O(N^2) worst case running time + O(1) memory

Quick Select (with random pivot)

Source: wikipedia: QuickSelect

Animation:

LeetCode Quick Select

Reference

LeetCode:

Source: wikipedia: QuickSelect

Animation:

Last updated

Was this helpful?