Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
Example 1:
Input: [3,2,1,5,6,4]
and k = 2
Output: 5
Example 2:
Input: [3,2,3,1,2,4,5,5,6]
and k = 4
Output: 4
Note:
You may assume k is always valid, 1 ≤ k ≤ array's length.
這道題讓我們求數組中第k大的數字,怎么求呢,當然首先想到的是給數組排序,然后求可以得到第k大的數字。先看一種利用 C++ 的 STL 中的集成的排序方法,不用我們自己實現,這樣的話這道題只要兩行就完事了,代碼如下:
解法一:
class Solution { public: int findKthLargest(vector<int>& nums, int k) { sort(nums.begin(), nums.end()); return nums[nums.size() - k]; } };
下面這種解法是利用了 priority_queue 的自動排序的特性,跟上面的解法思路上沒有什么區別,當然我們也可以換成 multiset 來做,一個道理,參見代碼如下:
解法二:
class Solution { public: int findKthLargest(vector<int>& nums, int k) { priority_queue<int> q(nums.begin(), nums.end()); for (int i = 0; i < k - 1; ++i) { q.pop(); } return q.top(); } };
上面兩種方法雖然簡潔,但是確不是本題真正想考察的東西,可以說有一定的偷懶嫌疑。這道題最好的解法應該是下面這種做法,用到了快速排序 Quick Sort 的思想,這里排序的方向是從大往小排。對快排不熟悉的童鞋們隨意上網搜些帖子看下吧,多如牛毛啊,總有一款適合你。核心思想是每次都要先找一個中樞點 Pivot,然后遍歷其他所有的數字,像這道題從大往小排的話,就把大於中樞點的數字放到左半邊,把小於中樞點的放在右半邊,這樣中樞點是整個數組中第幾大的數字就確定了,雖然左右兩部分各自不一定是完全有序的,但是並不影響本題要求的結果,因為左半部分的所有值都大於右半部分的任意值,所以我們求出中樞點的位置,如果正好是 k-1,那么直接返回該位置上的數字;如果大於 k-1,說明要求的數字在左半部分,更新右邊界,再求新的中樞點位置;反之則更新右半部分,求中樞點的位置;不得不說,這個思路真的是巧妙啊~
解法三:
class Solution { public: int findKthLargest(vector<int>& nums, int k) { int left = 0, right = nums.size() - 1; while (true) { int pos = partition(nums, left, right); if (pos == k - 1) return nums[pos]; if (pos > k - 1) right = pos - 1; else left = pos + 1; } } int partition(vector<int>& nums, int left, int right) { int pivot = nums[left], l = left + 1, r = right; while (l <= r) { if (nums[l] < pivot && nums[r] > pivot) { swap(nums[l++], nums[r--]); } if (nums[l] >= pivot) ++l; if (nums[r] <= pivot) --r; } swap(nums[left], nums[r]); return r; } };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/215
類似題目:
Kth Largest Element in a Stream
K Closest Points to Origin
參考資料:
https://leetcode.com/problems/kth-largest-element-in-an-array/
https://leetcode.com/problems/kth-largest-element-in-an-array/discuss/60294/Solution-explained