LeetCode 347. Top K Frequent Elements
https://leetcode.com/problems/top-k-frequent-elements/
Given a non-empty array of integers, return the k most frequent elements.
For example,
Given [1,1,1,2,2,3]
and k = 2, return [1,2]
.
Note:
- You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
- Your algorithm's time complexity must be better than O(n log n), where n is the array's size.
频率排序问题,先HASH到MAP里,然后按照频率可以用桶排序,也可以用优先序列。
STL里vector, map, priority_queue和pair都重新学习了一遍,非常方便。
还学习了不少C++11的东西,比如Lambda 表达式, auto,unordered_map,Range-based for Statement。可惜Dev-C++ 4.9.9.2不支持,所以又写了C++98版本。
- auto可以自动推断变量类型,如果不修改值的话,可以用const auto&。特别是对iterator很方便。
- unordered_map性能比map更好。
- Range-based for Statement更简洁,不需要写长串语句。可以对数组和STL sequence whose range is defined by a begin() and end()使用。Note that the auto keyword is preferred in the for-range-declaration portion of the statement.
- C++11还可以像数组一样初始化vector,赋值一串数字。
1 #include <iostream> 2 #include <utility> 3 #include <vector> 4 #include <map> 5 #include <queue> 6 //#include <unordered_map> 7 using namespace std; 8 9 class Solution 10 { 11 public: 12 vector<int> topKFrequent(vector<int>& nums, int k) 13 { 14 // unordered_map<int, int> frequencyMap; 15 map<int, int> frequencyMap; 16 vector<int>::const_iterator vecCIt; 17 18 // for (const auto &num : nums) 19 // frequencyMap[num] ++; 20 21 for (vecCIt = nums.begin(); vecCIt != nums.end(); vecCIt ++) 22 frequencyMap[*vecCIt] ++; 23 24 vector<int> res; 25 // pair<first, second> : first is number, second is frequency 26 // space is required between > and > 27 priority_queue< pair<int, int> > pq; 28 map<int, int>::const_iterator mapCIt; 29 30 /* 31 for (const auto &it : frequencyMap) 32 { 33 pq.push( make_pair(it.second, it.first) ); 34 35 if (pq.size() > (frequencyMap.size() - k)) 36 { 37 res.push_back(pq.top().second); 38 pq.pop(); 39 } 40 } 41 */ 42 43 for (mapCIt = frequencyMap.begin(); mapCIt != frequencyMap.end(); mapCIt ++) 44 { 45 pq.push( make_pair(mapCIt->second, mapCIt->first) ); 46 47 if ( pq.size() > (frequencyMap.size() - k) ) 48 { 49 res.push_back(pq.top().second); 50 pq.pop(); 51 } 52 } 53 54 return res; 55 } 56 }; 57 58 int main () 59 { 60 Solution testSolution; 61 int arrRes[] = {1, 1, 1, 2, 2, 3}; 62 // vector<int> result{ {1, 1, 1, 2, 2, 3} }; 63 vector<int> result(arrRes, arrRes + 6); 64 vector<int>::const_iterator vecCIt; 65 66 result = testSolution.topKFrequent(result, 2); 67 68 for (vecCIt = result.begin(); vecCIt != result.end(); vecCIt ++) 69 cout << *vecCIt << endl; 70 71 getchar(); 72 73 return 0; 74 }
1 #include <iostream> 2 #include <utility> 3 #include <vector> 4 #include <map> 5 #include <queue> 6 //#include <unordered_map> 7 using namespace std; 8 9 class Solution 10 { 11 public: 12 vector<int> topKFrequent(vector<int>& nums, int k) 13 { 14 // unordered_map<int, int> frequencyMap; 15 map<int, int> frequencyMap; 16 map<int, int>::const_iterator mapCIt; 17 vector<int>::const_iterator vecCIt; 18 19 // for (const auto &num : nums) 20 // frequencyMap[num] ++; 21 22 for (vecCIt = nums.begin(); vecCIt != nums.end(); vecCIt ++) 23 frequencyMap[*vecCIt] ++; 24 25 // 2-d vector based on frequency including frequecy 0 26 vector< vector<int> > buckets(nums.size() + 1); 27 vector<int>::const_iterator vecVCIt; 28 29 // Pay attention to .first/.second rather than ->first/->second 30 // for (auto mapCIt : frequencyMap) 31 // buckets[mapCIt.second].push_back(mapCIt.first); 32 33 // Numbers with the same frequency will be pushed back to the same buckets[i] 34 for (mapCIt = frequencyMap.begin(); mapCIt != frequencyMap.end(); mapCIt ++) 35 buckets[mapCIt->second].push_back(mapCIt->first); 36 37 vector<int> res; 38 /* 39 for (int i = buckets.size() - 1; i >= 0 && res.size() < k; i --) 40 { 41 for (int num : buckets[i]) 42 { 43 res.push_back(num); 44 if (res.size() == k) 45 break; 46 } 47 } 48 */ 49 50 // Find k numbers from the end of buckets to the front 51 for (int i = buckets.size() - 1; i >= 0 && res.size() < k; i --) 52 { 53 // Find the numbers in the same buckets[frequency] 54 for (vecVCIt = buckets[i].begin(); vecVCIt != buckets[i].end(); vecVCIt ++) 55 { 56 res.push_back(*vecVCIt); 57 if (res.size() == k) 58 break; 59 } 60 } 61 62 return res; 63 } 64 }; 65 66 int main () 67 { 68 Solution testSolution; 69 int arrRes[] = {1, 1, 1, 2, 2, 3}; 70 // vector<int> result{ {1, 1, 1, 2, 2, 3} }; 71 vector<int> result(arrRes, arrRes + 6); 72 vector<int>::const_iterator vecCIt; 73 74 result = testSolution.topKFrequent(result, 2); 75 76 for (vecCIt = result.begin(); vecCIt != result.end(); vecCIt ++) 77 cout << *vecCIt << endl; 78 79 getchar(); 80 81 return 0; 82 }
Lambda
http://baike.baidu.com/link?url=ZK0qILx8cb_8HUX13JvVUYdnlJBOvAPJdWF83wD-tDgQQwIQYAVzkhytf_3f7oidHLPeTyXSswQUWVW51W42Ri4Pp8vnnkFHBCloSSTyS9xIT2pAV8a2zknUKK1UkjhDMzr4O7-qrD6J-lkJxET4u_#4
C++ 中的 Lambda 表达式
https://msdn.microsoft.com/zh-cn/library/dd293608.aspx
C++ STL编程轻松入门
http://tech.163.com/05/0613/10/1M4EA0US00091589.html
STL (模板库)
http://baike.baidu.com/link?url=IZpCuRuYLNA31OpA8x1h3urVpkYzp2K8oCssu_nkwqOqFdrMhL9drd9FnAg-Ru_D2690xbC0e3Q-W9QxF47gsUXTXdMmS5Vl_jNeFK0GXOa
Map(STL关联容器)_百度百科
http://baike.baidu.com/subview/95826/8050590.htm#viewPageContent
map 类
https://msdn.microsoft.com/zh-CN/library/s44w4h2s.aspx
vector(Java与C++语言中的对象)_百度百科
http://baike.baidu.com/item/vector/3330482
vector 类
https://msdn.microsoft.com/zh-cn/library/9xd04bzs.aspx
vector可不可以像数组那样初始化-CSDN论坛-CSDN.NET-中国最大的IT技术社区
http://bbs.csdn.net/topics/250063911
STL List_百度百科
http://baike.baidu.com/view/4255293.htm
make_pair - C++ Reference
http://www.cplusplus.com/reference/utility/make_pair/
pair - C++ Reference
http://www.cplusplus.com/reference/utility/pair/
pair Structure
https://msdn.microsoft.com/zh-cn/library/t9zb6cdt(v=vs.110).aspx
auto(C/C++语言存储类型)_百度百科
http://baike.baidu.com/link?url=U31tXzre2-JD9poBPGYKojek5DhtJGkafkk-YiG1-E_-v6ClnMUBIMe5JZaVvgKWp1IJUPr8MmXskPcngzigEFqhzaIdrlfDZC7cJ9vluCm
auto(C++)
https://msdn.microsoft.com/zh-cn/library/dd293667(v=vs.140).aspx
c++11_百度百科
http://baike.baidu.com/view/7021472.htm
Range-based for Statement (C++)
https://msdn.microsoft.com/en-us/library/jj203382.aspx
priority_queue 类
https://msdn.microsoft.com/zh-cn/library/4ef4dae9.aspx
priority_queue - C++ Reference
http://www.cplusplus.com/reference/queue/priority_queue/
unordered_map 类
https://msdn.microsoft.com/zh-cn/library/bb982522.aspx
unordered_map - C++ Reference
http://www.cplusplus.com/reference/unordered_map/unordered_map/
- Python同样先统计频率,再使用heap或者桶排序取K largest。学习了collections.defaultdict(list)来初始化dictionary,以及collectinos.Counter(),heapq.nlargest()。
- Top K Frequent Elements - LeetCode
- Python O(n) solution without sort, without heap, without quickselect - LeetCode Discuss
- defaultdict - collections — Container datatypes — Python 3.7.4 documentation
- Counter - collections — Container datatypes — Python 3.7.4 documentation
- heapq — Heap queue algorithm — Python 3.7.4 documentation
- nlargest - cpython: 54c93e0fe79b Lib/heapq.py
- dict.get - Built-in Types — Python 3.7.4 documentation
- reversed - Built-in Functions — Python 3.9.0a0 documentation
1 class Solution: 2 # heap 3 def topKFrequent1(self, nums: List[int], k: int) -> List[int]: 4 count = collections.Counter(nums) 5 6 return heapq.nlargest(k, count.keys(), key=count.get) 7 8 # bucket sort without collections module 9 def topKFrequent2(self, nums: List[int], k: int) -> List[int]: 10 frequencies = {} 11 12 for num in nums: 13 if num not in frequencies: 14 frequencies[num] = 1 15 else: 16 frequencies[num] += 1 17 18 buckets = {} 19 20 for key, count in frequencies.items(): 21 if count not in buckets: 22 buckets[count] = [key] 23 else: 24 buckets[count].append(key) 25 26 result = [] 27 28 # given that max(frequency) <= len(nums), max(index of buckets) <= len(nums) 29 for times in range( len(nums), 0, -1 ): 30 if times in buckets: 31 result.extend( buckets[ times ] ) 32 33 if len(result) >= k: 34 return result[:k] 35 36 return result[:k] 37 38 # bucket sort with collections module 39 def topKFrequent(self, nums: List[int], k: int) -> List[int]: 40 # pay attention to the initialisation of dictionary 41 buckets = collections.defaultdict(list) 42 43 for key, count in collections.Counter(nums).items(): 44 buckets[count].append(key) 45 46 result = [] 47 48 for times in reversed( range( len(nums) + 1 ) ): 49 result.extend( buckets[ times ] ) 50 51 if len(result) >= k: 52 return result[:k] 53 54 return result[:k]