用于求解 Kth Element 问题,使用快速排序的 partition() 进行实现。需要先打乱数组,否则最坏情况下时间复杂度为 O(N2)。
用于求解 TopK Elements 问题,通过维护一个大小为 K 的堆,堆中的元素就是 TopK Elements。
堆排序也可以用于求解 Kth Element 问题,堆顶元素就是 Kth Element。
快速选择也可以求解 TopK Elements 问题,因为找到 Kth Element 之后,再遍历一次数组,所有小于等于 Kth
Element 的元素都是 TopK Elements。
可以看到,快速选择和堆排序都可以求解 Kth Element 和 TopK Elements 问题。
215. Kth Largest Element in an Array
时间复杂度 O(NlogN),空间复杂度 O(1)。
class Solution {
public:
int findKthLargest(vector& nums, int k) {
assert(k>=1&&k<=nums.size());
sort(nums.begin(), nums.end());
return nums[nums.size()-k];
}
};
时间复杂度 O(NlogK),空间复杂度 O(K)。
class Solution {
public:
int findKthLargest(vector& nums, int k) {
priority_queue, greater> pq;
for (int i = 0; i < nums.size(); ++i)
{
pq.push(nums[i]);
if (pq.size() > k) //维护优先队列大小为k,保证队列中第k个元素最小
pq.pop();
}
return pq.top();
}
};
时间复杂度 O(N),空间复杂度 O(1)
class Solution1 {
public:
int findKthLargest(vector& nums, int k) {
assert(k >= 1 && nums.size() >= k);
srand(time(NULL));
return findKthLargest(nums, 0, nums.size() - 1, k - 1);
}
private:
int findKthLargest(vector& nums, int l, int r, int k)
{
if (l == r)
return nums[l];
int p = partition(nums, l, r);
if (p == k)
return nums[p];
else if (p < k)
return findKthLargest(nums, p + 1, r, k);
else
return findKthLargest(nums, l, p - 1, k);
}
//从大到小排序
int partition(vector& nums, int l, int r)
{
swap(nums[l], nums[rand() % (r - l + 1) + l]);
int v = nums[l];
//[l+1, gt]>v, (gt,i)<=v
int gt = l;
int i = l + 1;
while (i <= r)
{
if (nums[i] > v)
swap(nums[i], nums[++gt]);
++i;
}
swap(nums[l], nums[gt]);
return gt;
}
};
347. Top K Frequent Elements
class Solution {
public:
vector topKFrequent(vector& nums, int k) {
unordered_map m; //存储<值,频率>对儿
for (auto num : nums)
++m[num];
assert(m.size() >= k); //保证有至少k个不同的元素
//优先队列中存储的<频率,值>对儿
priority_queue, vector>, greater>> pq;
for (auto it = m.begin(); it != m.end(); ++it)
{
pq.push(make_pair(it->second, it->first));
if (pq.size() > k) //注意此处条件的使用,可以避免元素比较;如果是==的话,还需多一次比较操作
pq.pop();
}
vector res;
while (!pq.empty())
{
res.push_back(pq.top().second);
pq.pop();
}
return res;
}
};
451. Sort Characters By Frequency
class Solution {
public:
string frequencySort(string s) {
if(s=="")
return s;
unordered_map record;
for(int i = 0;i>vRecord(record.begin(), record.end());
sort(vRecord.begin(), vRecord.end(), pair_cmp);
string res = "";
for(int i = 0;i &lhs,const pair &rhs)
{
return lhs.second>rhs.second;
}
};
75. Sort Colors
本质是三路快速排序思想。
class Solution {
public:
void sortColors(vector& nums) {
//[0, zero] == 0
int zero = -1;
//[two, n-1] == 2;
int n = nums.size();
int two = n;
int i = 0;
while(i