zoukankan      html  css  js  c++  java
  • LeetCode 【347. 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].

    其实最简单的就是想到就是用一个小顶堆实现,如果堆中元素个数小于K,则插入元素,如果大于K,则和堆顶比较,如果大于堆顶,则弹出堆顶,插入新元素。

    自己实现红黑树有点难,好在C++ STL容器中,map,set和priority_queue都是实现了红黑树结构的,所以可以拿来用。首先这边上一种我最开始自己实现的算法,通过排序来实现的。

    1.设置一个unorderd_map<int,int>对每一个vector中的数据进行统计,统计出个数,然后将pair<int,int>放入vector中自己定义排序的比较算法,选取前K个,最后出来时间上还可以 Beate 70%+

    代码也很容易理解,如下:

    class Solution {
    public:
    
        vector<int> topKFrequent(vector<int>& nums, int k) {
            unordered_map<int,int> myMap;
            for( int i = 0; i < nums.size(); i++ ){
                myMap[nums[i]]++;
            }
            vector<PAIR> mapMember;
            for( auto m : myMap){
                mapMember.push_back(m);
            }
            sort( mapMember.begin(),mapMember.end(),myCMP);
            vector<int> result;
            for( int i = 0; i < k; i++ ){
                result.push_back(mapMember[i].first);
            }
            return result;
        }
    private:
        typedef pair<int,int> PAIR;
        static bool myCMP (PAIR& num1, PAIR& num2){
                return num1.second > num2.second;
        }
    };
    

    思路2:用最小堆:首先需要了解一下C++中的优先队列priority_queue进行一个了解,priority_queue 优先级队列是一个拥有权值概念的单向队列queue,在这个队列中,所有元素是按优先级排列的(也可以认为queue是个按进入队列的先后做为优先级的优先级队列——先进入队列的元素优先权要高于后进入队列的元素)。他的模板声明带有三个参数,priority_queue<Type, Container, Functional>Type 为数据类型, Container 为保存数据的容器,Functional 为元素比较方式第一个是元素类型,这边的话就是pair<int,int> 第二个是保存数据的容器,一般默认使用vector,第三个是比较方式,如果不定义,默认是大顶堆,这边因为需要小顶堆实现,所以使用greater<>;

    代码:

    typedef pair<int, int> P;
    class Solution {
    public:
    	vector<int> topKFrequent(vector<int>& nums, int k) {
    		unordered_map<int, int> cnt;
    		for (int x : nums) 	cnt[x] ++;
    		priority_queue<P, vector<P>, greater<P> > q;
    		for (auto &x : cnt) {
    			if (q.size() < k)
    				q.push(make_pair(x.second, x.first));
    			else {
    				if (q.top().first < x.second) {
    					q.pop();
    					q.push(make_pair(x.second, x.first));
    				}
    			}
    		}
    		vector<int> ans;
    		while (!q.empty()) {
    			ans.push_back(q.top().second);
    			q.pop();
    		}
    		return ans;
    	}
    };
    

    这边需要注意,这里pair中,first和second通过make_pair掉位置了,为什么呢?因为对于pair来说,默认的比较操作是比较first成员的,但是我们这边需要比较的second的数据,所以需要调一个位置。

  • 相关阅读:
    快速排序
    Java LinkedList
    Java ArrayList
    Java ReentrantLock
    Java Timer
    Java 管道PipedInputStream PipedOutStream PipedReader PipedWriter
    6. Samba服务和防火墙配置笔记
    5. 网络配置与FTP服务笔记
    3.vi 和软件安装
    2 . Linux常见命令
  • 原文地址:https://www.cnblogs.com/rockwall/p/5780315.html
Copyright © 2011-2022 走看看