Description
Given an integer array nums
and an integer k
, return the kth
largest element in the array.
Note that it is the kth
largest element in the sorted order, not the kth
distinct element.
You must solve it in O(n)
time complexity.
Example 1:
Input: nums = [3,2,1,5,6,4], k = 2 Output: 5
Example 2:
Input: nums = [3,2,3,1,2,4,5,5,6], k = 4 Output: 4
Constraints:
1 <= k <= nums.length <= 105
-104 <= nums[i] <= 104
Code
Quick Select
Time Complexity: , Space Complexity:
若沒有 randonmized input,runtime 會慢很多(240ms),有的話只需要(102ms)。
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
// randonmize input to gaurantee O(n)
random_device rd;
mt19937 g(rd());
shuffle(nums.begin(), nums.end(), g);
int left = 0, right = nums.size() - 1;
k = nums.size() - k;
while(left < right) {
int index = quick_select(nums, left, right);
if(index == k) return nums[index];
else if(index < k) left = index + 1;
else right = index - 1;
}
return nums[left];
}
int quick_select(vector<int>& nums, int front, int end) {
int pivot = nums[end];
int i = front - 1;
for(int j = front; j < end; j++) {
if(nums[j] < pivot) {
i++;
swap(nums[j], nums[i]);
}
}
i++;
swap(nums[i], nums[end]);
return i;
}
};
partial sorting(nth_element & partial_sort)
Time Complexity: , Space Complexity:
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
nth_element(nums.begin(), nums.begin() + k - 1, nums.end(), greater<int>());
return nums[k - 1];
}
};
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
nth_element(nums.begin(), nums.begin() + k - 1, nums.end(), [](const int a, const int b){return a > b;});
return nums[k - 1];
}
};
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
k = nums.size() - k;
nth_element(nums.begin(), nums.begin() + k, nums.end());
return nums[k];
}
};
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
partial_sort(nums.begin(), nums.begin() + k, nums.end(), greater<int>());
return nums[k - 1];
}
};
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
k = nums.size() - k;
partial_sort(nums.begin(), nums.begin() + k + 1, nums.end());
return nums[k];
}
};
priority_queue
default 為 max heap,而 multiset
default 為 min heap。
在寫 custom cmp 時,記得只有 priority_queue
的大小方向和其他人相反。
Max Heap
Time Complexity: , Space Complexity:
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int> p;
for(auto n: nums) {
p.push(n);
}
for(int i = 0; i < k - 1; i++) {
p.pop();
}
return p.top();
}
};
注意 multiset 的 cmp 大小比較順序。
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
auto cmp = [](const int a, const int b) {return a > b;};
multiset<int, decltype(cmp)> m(cmp);
for(auto n: nums) {
m.insert(n);
}
for(int i = 0; i < k - 1; i++) m.erase(m.begin());
return *m.begin();
}
};
Min Heap
Time Complexity: , Space Complexity:
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int, vector<int>, greater<int>> min_heap;
for(auto& n: nums) {
min_heap.push(n);
if(min_heap.size() > k)
min_heap.pop();
}
return min_heap.top();
}
};
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
auto cmp = [](const int a, const int b){return a > b;};
priority_queue<int, vector<int>, decltype(cmp)> p(cmp);
for(auto n: nums) {
p.push(n);
if(p.size() > k)
p.pop();
}
return p.top();
}
};
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
multiset<int> m;
for(auto n: nums) {
m.insert(n);
if(m.size() > k) {
m.erase(m.begin());
}
}
return *m.begin();
}
};
Counting Sort
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
int size = 20005;
vector<int> count(size, 0);
for(auto n: nums) {
int index = n + 10000;
count[index]++;
}
for(int i = 1; i < count.size(); i++) {
count[i] += count[i - 1];
}
int n = nums.size();
vector<int> sorted(n);
for(int i = n - 1; i >= 0; i--) {
sorted[count[nums[i] + 10000] - 1] = nums[i];
count[nums[i] + 10000]--;
}
k = n - k;
return sorted[k];
}
};