leetcode347 前K个高频元素
暴力的做法,先遍历一遍数组,然后把出现的数字与对应的出现次数放置在一个map中,而map自己无法根据value来排序,所以将map中的数据放置进一个vector中进行排序,撰写了一个函数用于排序的判定,最后输出前K个元素即可。贴代码
1 typedef pair<int,int> PAIR; 2 bool cmp_val(const PAIR &left,const PAIR &right) 3 { 4 return left.second > right.second; 5 } 6 class Solution { 7 public: 8 vector<int> topKFrequent(vector<int>& nums, int k) 9 { 10 map<int,int> res_temp; 11 vector<int> res; 12 for(auto temp:nums) 13 { 14 if(!res_temp.count(temp)) 15 { 16 res_temp.insert(pair<int,int>(temp,1)); 17 } 18 else 19 { 20 (res_temp.find(temp)->second)++; 21 } 22 } 23 vector<PAIR> vec(res_temp.begin(),res_temp.end()); 24 sort(vec.begin(),vec.end(),cmp_val); 25 vector<PAIR>::iterator it_temp = vec.begin(); 26 for(int i = 0 ; i < k ; i++) 27 { 28 res.push_back(it_temp->first); 29 it_temp++; 30 } 31 return res; 32 } 33 };
接触到了一种新的数据结构,堆,本质上是二叉树,其特殊性质是父节点一定小于或者大于其两个子节点,分别为小顶堆与大顶堆。可以在C++中通过priority_queue这一数据结构实现。还是先通过map实现遍历,然后建立一个K大小的小顶堆,如果堆的元素个数小于 k,就可以直接插入堆中。如果堆的元素个数等于 kk,则检查堆顶与当前出现次数的大小。如果堆顶更大,说明至少有 kk 个数字的出现次数比当前值大,故舍弃当前值;否则,就弹出堆顶,并将当前值插入堆中。最后输出堆中所有元素的first值,贴代码。
1 class Solution { 2 public: 3 static bool cmp(pair<int, int>& m, pair<int, int>& n) { 4 return m.second > n.second; 5 } 6 vector<int> topKFrequent(vector<int>& nums, int k) 7 { 8 map<int,int> res_temp; 9 vector<int> res; 10 for(auto temp:nums) 11 { 12 if(!res_temp.count(temp)) 13 { 14 res_temp.insert(pair<int,int>(temp,1)); 15 } 16 else 17 { 18 (res_temp.find(temp)->second)++; 19 } 20 } 21 priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(&cmp)> q(cmp); 22 for(auto& [num,count] : res_temp) 23 { 24 if(q.size() == k) 25 { 26 if(q.top().second<count) 27 { 28 q.pop(); 29 q.emplace(num,count); 30 } 31 } 32 else 33 { 34 q.emplace(num,count); 35 } 36 } 37 while(!q.empty()) 38 { 39 res.push_back(q.top().first); 40 q.pop(); 41 } 42 return res; 43 } 44 };
还有一种方法,利用了快速排序的方法,快速排序的原理就是随机选定一个界限值,将大于该值的放在该值的左或者右,从而进行递归,而该例中不需要完成所有的排序,只需要得出k个最大的即可。如第一次排序出n个较大值,若n比k大,则继续进行排序,选择出k个最大的,若n比k小,先将n个值存储,然后在剩余值中选取k-n个较大值,同样能够完成,贴代码。
1 class Solution { 2 public: 3 void quicksort(vector<pair<int,int>>& v,int start,int end, vector<int>& ret,int k) 4 { 5 int picked = rand()%(end - start +1) + start; 6 swap(v[start],v[picked]); 7 int pivot = v[start].second; 8 int index = start; 9 for(int i = start+1 ; i <= end ; i++) 10 { 11 if(v[i].second>=pivot) //将比pivot大的都放在index的左边 12 { 13 swap(v[index+1],v[i]); 14 index++; 15 } 16 } 17 swap(v[start],v[index]); 18 if(k<=index-start) 19 { 20 quicksort(v,start,index-1,ret,k); 21 } 22 else 23 { 24 for(int i = start ; i <= index ; i++) 25 { 26 ret.push_back(v[i].first); 27 } 28 if(k>index-start+1) 29 { 30 quicksort(v,index+1,end,ret,k-(index-start+1)); 31 } 32 } 33 } 34 vector<int> topKFrequent(vector<int>& nums, int k) 35 { 36 map<int,int> res_temp; 37 vector<int> res; 38 for(auto temp:nums) 39 { 40 if(!res_temp.count(temp)) 41 { 42 res_temp.insert(pair<int,int>(temp,1)); 43 } 44 else 45 { 46 (res_temp.find(temp)->second)++; 47 } 48 } 49 vector<pair<int,int>> values; 50 for(auto &temp:res_temp) 51 { 52 values.push_back(temp); 53 } 54 quicksort(values,0,values.size()-1,res,k); 55 return res; 56 } 57 };
另一种快速排序的写法,本质上还是类似的。
1 class Solution { 2 public: 3 vector<int> topKFrequent(vector<int>& nums, int k) 4 { 5 map<int,int> countMap; 6 for(auto temp:nums) 7 { 8 if(!countMap.count(temp)) 9 { 10 countMap.insert(pair<int,int>(temp,1)); 11 } 12 else 13 { 14 (countMap.find(temp)->second)++; 15 } 16 } 17 vector<pair<int,int>> countVec; 18 for(auto &temp:countMap) 19 countVec.push_back(temp); 20 vector<int> resVec; 21 quicksort(countVec,0,countVec.size()-1,k,resVec); 22 return resVec; 23 } 24 void quicksort(vector<pair<int,int>>& countVec,int start,int end,int k,vector<int>& resVec) 25 { 26 int picked = rand()%(end - start +1) + start; 27 swap(countVec[start],countVec[picked]); 28 int pivot = countVec[start].second; 29 int index = start; 30 for(int i = start+1 ; i <= end ; i++) 31 { 32 if(countVec[i].second>pivot) 33 { 34 swap(countVec[index+1],countVec[i]); 35 index++; 36 } 37 } 38 swap(countVec[start],countVec[index]); 39 if(index+1>k) 40 quicksort(countVec,start,index-1,k,resVec); 41 else if(index+1 == k) 42 { 43 for(int i = 0 ; i <= index ; i++) 44 resVec.push_back(countVec[i].first); 45 } 46 else 47 quicksort(countVec,index+1,end,k,resVec); 48 } 49 };

浙公网安备 33010602011771号