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 }
Priority queue

 

 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 }
Bucket sort

 

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/


 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]
View Python Code

 

posted on 2016-05-20 23:43  浩然119  阅读(842)  评论(0编辑  收藏  举报