215. Kth Largest Element in an Array (Medium)
题目描述:找到第 k 大的元素。
快速选择 :时间复杂度 O(N),空间复杂度 O(1)
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
if(nums.empty()||nums.size()<k||k<=0)
return 0;
int pos=partition(nums,0,nums.size()-1);
while(pos!=k-1){
if(pos>k-1){
partition(nums,0,pos-1);
}
else if(pos<k-1)
partition(nums,pos+1,nums.size()-1);
}
return nums[pos];
}
int partition(vector<int> &nums,int start,int end){
int left=start;
int right=end;
int num=nums[start];
while(left<right){
while(nums[right]<=num&&left<right)right--;
while(nums[left]>=num&&left<right)left++;
if(left<right)
swap(nums[left],nums[right]);
}
swap(nums[start],nums[right]);
return right;
}
};
//构建小根堆
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
if(nums.empty()||nums.size()<k||k<=0)
return 0;
priority_queue<int,vector<int>,greater<int>>q;
for(int i=0;i<nums.size();++i){
if(q.size()<k)
q.push(nums[i]);
else
{
if(nums[i]>q.top())
{ q.pop();
q.push(nums[i]);
}
}
}
if(!q.empty())
return q.top();
return 0;
}
};
347. Top K Frequent Elements (Medium)
Given [1,1,1,2,2,3] and k = 2, return [1,2].
思路:用一个unordered_map(无序的map)保存nums中的值与它出现次数的映射关系。再基于优先级队列,按照出现频率排序,每一次输出队列的top()直到第k个数为止;
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
vector<int> res;
if(nums.empty()||nums.size()<k||k<=0)
return res;
int size=nums.size();
unordered_map<int,int>mp;
priority_queue<pair<int,int>>pq;
for(auto i:nums)mp[i]++;
for(auto p:mp)pq.push(pair<int,int>(p.second,p.first));
while(k--){
res.push_back(pq.top().second);
pq.pop();
}
return res;
}
};
//
struct key_value{
int key;
int num;
};
bool cmp(const key_value &x,const key_value &y){
return x.num>y.num;
}
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
vector<int> res;
if(nums.empty()||nums.size()<k||k<=0)
return res;
vector<key_value>keyv;
sort(nums.begin(),nums.end());
int j=0;
int count=1;
for(int i=1;i<nums.size();++i){
if(nums[i]==nums[j])
count++;
else
{ key_value kv;
kv.key=nums[j];
kv.num=count;
keyv.push_back(kv);
count=1;
j=i;
}
}
key_value kv;
kv.key=nums[j];
kv.num=count;
keyv.push_back(kv);
sort(keyv.begin(),keyv.end(),cmp);
int i=0;
while(k--){
res.push_back(keyv[i].key);
i++;
}
return res;
}
};
451. Sort Characters By Frequency (Medium)
思路:与上面的解题思路大体一致,只是容器存放数据的类型改变,应注意pair的存放与读取,什么时候需要first什么时候需要second;
class Solution {
public:
string frequencySort(string s) {
if(s.size()<=0)
return "";
string res="";
unordered_map<char,int>mp;
priority_queue<pair<int,char>>pq;
for(auto c:s)mp[c]++;
for(auto p:mp)pq.push(pair<int,char>(p.second,p.first));
while(!pq.empty()){
pair<int,char>tmp1;
tmp1=pq.top();
pq.pop();
while(tmp1.first--){
res+=tmp1.second;
}
}
return res;
}
};
4、荷兰国旗问题
荷兰国旗包含三种颜色:红、白、蓝。
有三种颜色的球,算法的目标是将这三种球按颜色顺序正确地排列。
它其实是三向切分快速排序的一种变种,在三向切分快速排序中,每次切分都将数组分成三个区间:小于切分元素、等于切分元素、大于切分元素,而该算法是将数组分成三个区间:等于红色、等于白色、等于蓝色。
class Solution {
public:
void sortColors(vector<int>& nums) {
if(nums.empty())
return;
int left=-1;
int right=nums.size();
int i=0;
while(i<right){
if(nums[i]==0)
swap(nums[i++],nums[++left]);
else if(nums[i]==2)
swap(nums[i],nums[--right]);
else
++i;
}
}
};