[LeetCode] 215. Kth Largest Element in an Array 數組中第k大的數字


 

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

 

類似題目:

Wiggle Sort II

Top K Frequent Elements

Third Maximum Number

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

https://leetcode.com/problems/kth-largest-element-in-an-array/discuss/60309/C%2B%2B-PartitionMax-Heappriority_queuemultiset

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM