排序算法总结(2.11) |
|
|
Kth元素(2.12) | 几种方法,关键:堆、快排 还不是很熟练 | ※ |
2. 出现频率最多的 k 个元素 | 桶排序,未作出 | ※ |
3. 按照字符出现次数对字符串排序 | 同上ok |
|
4. 按颜色进行排序 | Ok |
|
1. Kth Element
215. Kth Largest Element in an Array (Medium)
https://leetcode-cn.com/problems/kth-largest-element-in-an-array/submissions/
1. 采用库函数,排序后选元素,时间复杂度O(NlogN),空间复杂度O(1)
int findKthLargest(vector<int>& nums, int k) {
sort(nums.begin(),nums.end());
return nums[nums.size()-k];
}
2. 堆排序
class Solution {
public:
void adjustDown(vector<int>& nums,int i,int n){
int child,tmp=nums[i];
for(;2*i+1<n;i=child){
child=2*i+1;
if(child!=n-1&&nums[child+1]>nums[child]) child++;
if(nums[child]>tmp) nums[i]=nums[child];
else break;
}
nums[i]=tmp;
}
int findKthLargest(vector<int>& nums, int k) {
int n=nums.size();
for(int i=n/2;i>=0;i--)
adjustDown(nums,i,n);
for(int i=n-1,j=1;i>0&&j<k;i--,j++){
nums[0]=nums[i];
adjustDown(nums,0,i);
}
return nums[0];
}
};
3. 利用最小堆
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int,vector<int>,greater<int>> store;
for(int i=0;i<nums.size();i++){
store.push(nums[i]);
if(store.size()>k) store.pop();
}
return store.top();
}
};
4. 快排:时间复杂度O(n)
class Solution {
void swap(int &a,int &b){
int tmp=a;
a=b;
b=tmp;
}
int partition(vector<int>& nums,int left,int right){
int tmp=nums[right];
int i=left,j=left;
for(;j<right;j++){
if(nums[j]<=tmp){
swap(nums[i],nums[j]);
i++;
}
}
swap(nums[i],nums[right]);
return i;
}
int select(vector<int>& nums,int left,int right,int k){
if(left==right) return nums[left];
int cut=partition(nums,left,right);
int curr=cut-left+1;
if(k==curr) return nums[cut];
else if(k<curr) return select(nums,left,cut-1,k);
else return select(nums,cut+1,right,k-curr);
return 0;
}
public:
int findKthLargest(vector<int>& nums, int k) {
int kmin=nums.size()-k+1;
return select(nums,0,nums.size()-1,kmin);
}
};
2. 出现频率最多的 k 个元素
347. Top K Frequent Elements (Medium)
https://leetcode-cn.com/problems/top-k-frequent-elements/
1. 利用内置排序函数
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
map<int,int> mp;
for(int i=0;i<nums.size();i++)
mp[nums[i]]++;
vector<pair<int,int>> sort_num(mp.begin(),mp.end());
sort(sort_num.begin(),sort_num.end(),[](pair<int,int> &a,pair<int,int> &b){ return a.second>b.second;});
vector<int> res;
for(int i=0;i<k;i++)
res.push_back(sort_num[i].first);
return res;
}
};
2. 利用优先队列:最大堆
class Solution {
public:
struct cmp{
bool operator()(pair<int,int> &a,pair<int,int> &b){
return a.second<b.second;}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
map<int,int> mp;
for(int i=0;i<nums.size();i++)
mp[nums[i]]++;
priority_queue<pair<int,int>,vector<pair<int,int>>,cmp> hp;
for(auto it:mp){
hp.push(it);
}
vector<int> res(k);
for(int i=0;i<k;i++){
res[i]=hp.top().first;
hp.pop();
}
return res;
}
};
3. 桶排序
设置若干个桶,每个桶存储出现频率相同的数。桶的下标表示数出现的频率,即第 i 个桶中存储的数出现的频率为 i。把数都放到桶之后,从后向前遍历桶,最先得到的 k 个数就是出现频率最多的的 k 个数。
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
map<int,int> mp;
for(int i=0;i<nums.size();i++)
mp[nums[i]]++;
vector<vector<int>> bucket(nums.size()+1);
for(auto it:mp){
bucket[it.second].push_back(it.first);
}
vector<int> res(k);
for(int i=bucket.size()-1;i>=0;i--){
for(int j=0;j<bucket[i].size();j++){
res[--k]=bucket[i][j];
if(k==0) return res;
}
}
return res;
}
};
3. 按照字符出现次数对字符串排序
451. Sort Characters By Frequency (Medium)
https://leetcode-cn.com/problems/sort-characters-by-frequency/
解法类似2
4. 按颜色进行排序
75. Sort Colors (Medium)
https://leetcode-cn.com/problems/sort-colors/solution/yan-se-fen-lei-by-leetcode/