Categories
不学无术

LeetCode347. 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.

思路

题目中明确提示要O(nlogn)复杂度了…
我的做法是先统计结果到一个map<value, count>里面,然后用一个大小为k的最小堆处理,每次从map中读取元素时根据count值判断是否要替换掉堆顶。由于STL的map是用红黑树实现的,所以时间复杂度就保证了,要再快的话就直接用hash函数吧,可以到O(n)。维护k大小的堆,算最差情况,建堆复杂度是O(k),维护复杂度是O(logk), 要维护M-k次,其中0<M<=N是map中的元素个数.
代码

struct CountVal{
    int val;
    int count;
    CountVal(int _val, int _count){
        val = _val;
        count = _count;
    }
};
bool compareObj(const CountVal& x, const CountVal& y){
    return x.count > y.count;
}
class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        map<int, int> countMap;
        vector<CountVal> counts;
        for(int i=0; i<nums.size(); i++){
            if(countMap.count(nums[i]) == 0)
                countMap[nums[i]] = 1;
            else
                countMap[nums[i]]++;
        }
        int count = 0;
        for(auto it=countMap.begin(); it!=countMap.end(); it++){
            CountVal item(it->first, it->second);
            if(count < k){
                counts.push_back(item);
                if(count == k-1){
                    make_heap(counts.begin(), counts.end(), compareObj);
                }
            } else {
                if (it->second > counts.front().count) {
                    pop_heap(counts.begin(), counts.end(), compareObj);
                    counts.pop_back();
                    counts.push_back(item);
                    push_heap(counts.begin(), counts.end(), compareObj);
                }
            }
            count++;
        }
        vector<int> results;
        for(auto it=counts.begin(); it!=counts.end(); it++){
            results.push_back(it->val);
        }
        return results;
    }
};

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.