zoukankan      html  css  js  c++  java
  • 347,23

    典型可以使用优先队列的。

    (小顶堆)

    class Solution {
    public:
        vector<int> topKFrequent(vector<int>& nums, int k) {
            
            assert(k>0);
            
            //统计每个元素出现的频率
            unordered_map<int,int> freq;   //freq<元素,频率>
            for(int i=0; i<nums.size();i++){
                freq[nums[i]] ++;  
            }
            
            assert(k<=freq.size());
            
            //扫描freq,维护当前出现频率最高的k个元素
            //在优先队列中,按照频率排序,所以数据对是(频率,元素)的形式.因为在pair中比较时,先比较的是频率
            priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>> > pq;  //优先队列,从小到大排序
            
            for(unordered_map<int, int>::iterator iter = freq.begin(); iter!=freq.end(); iter++){
                
                //当前的优先队列已经维护了k个出现频率最高的元素
                if(pq.size() == k){
                    if(iter->second > pq.top().first){ //iter<元素,频率>
                        pq.pop();   //将更小频率的元素扔掉
                        pq.push(make_pair(iter->second, iter->first));
                    }
                }
                else
                    pq.push(make_pair(iter->second, iter->first));
            }
            
            vector<int> res;
            while(!pq.empty()){
                res.push_back(pq.top().second);
                pq.pop();
            }
            return res;
        }
    };
    
    

     但是若k和n差不多大,方法二就比较耗时了。则方法三的优势就很明显了。

    typedef pair<int, int> PAIR; 
    class Solution {
    public:
        
        static int cmp(PAIR &a, PAIR &b){
            
            return a.second>b.second;
        }
        
        vector<int> topKFrequent(vector<int>& nums, int k) {
            
            vector<int> v;
            map<int, int> m;
            vector<PAIR> pair_vec;
            for(int i=0;i<nums.size();++i){
                
                m[nums[i]]++;
            }
            for(map<int,int>:: iterator it = m.begin(); it!=m.end(); ++it){
                
                pair_vec.push_back(make_pair(it->first, it->second));
            }
            sort(pair_vec.begin(), pair_vec.end(),cmp);
            vector<PAIR>::iterator it = pair_vec.begin();
            while(k--){
                
                v.push_back(it->first);
                ++it;
            }
            
            return v;
        }
        
    };

    合并前的k个链表是有序的,最终合并后的链表也是有序的

     使用优先队列(小顶堆),先将K个链表的首元素都加入最小堆中,然后每次取出最小的那个元素加入到最终的链表中。然后把取出元素的下一个元素再加入堆中,下次仍从堆中取出最小的元素做相同的操作。以此类推,直到堆中没有元素了。此时返回合成链表的首结点。

     这里注意两点:

    1)比较函数的写法;

    2)由于优先队列默认是大顶堆,它重载了< ,优先队列会认为 a < b ,即 b 的优先级比 a 高,所以 b会被先出队,假设 a->val > b->val 为 TRUE,这样就实现了关键字小的元素先出队。它和sort比较函数的写法是相反的。

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        
        struct cmp{
            bool operator()(ListNode* a, ListNode* b){
                return a->val > b->val;
            } 
        };
        
        ListNode* mergeKLists(vector<ListNode*>& lists) {
            priority_queue<ListNode*, vector<ListNode*>,cmp> q;
            
            //将k个链表的首结点推入优先队列中
            for(int i=0;i<lists.size();i++)
                if(lists[i])
                    q.push(lists[i]);
            
            ListNode* dummy = new ListNode(-1), *cur = dummy, *t = NULL;
            while(!q.empty()){
                t = q.top();
                q.pop();
                cur->next = t;
                cur = cur->next;
                if(cur->next)
                    q.push(cur->next);
            }
            return dummy->next;
        }
    };
  • 相关阅读:
    一个简单的knockout.js 和easyui的绑定
    knockoutjs + easyui.treegrid 可编辑的自定义绑定插件
    Knockout自定义绑定my97datepicker
    去除小数后多余的0
    Windows Azure Web Site (15) 取消Azure Web Site默认的IIS ARR
    Azure ARM (1) UI初探
    Azure Redis Cache (3) 创建和使用P级别的Redis Cache
    Windows Azure HandBook (7) 基于Azure Web App的企业官网改造
    Windows Azure Storage (23) 计算Azure VHD实际使用容量
    Windows Azure Virtual Network (11) 创建VNet-to-VNet的连接
  • 原文地址:https://www.cnblogs.com/Bella2017/p/10421960.html
Copyright © 2011-2022 走看看