leetcode堆、优先队列(347. 前 K 个高频元素、295. 数据流的中位数)

在这里插入图片描述

class Solution {
public:
    struct node{
        int fi,se;
    };
    vector<node> q;
    void heapmodify(int i)
    {
        int len=q.size()-1;
        for(;(i<<1)+1<=len;)
        {
            int lchild=(i<<1)+1;
            int rchild=(i<<1)+2;
            int small=i;
            if(lchild<=len&&q[lchild].se<q[small].se) small=lchild;
            if(rchild<=len&&q[rchild].se<q[small].se) small=rchild;
            if(i!=small)
            {
                swap(q[small],q[i]);
                i=small;
            }
            else break;
        }
    }
    void addnum()
    {
        int i=q.size()-1;
        for(;(i-1)>>1>=0;)
        {
            int fa=(i-1)>>1;
            if(q[i].se<q[fa].se)
            {
                swap(q[i],q[fa]);
                i=fa;
            }
            else break;
        }
    }
    void build(int len)
    {
        for(int i=len/2;i>=0;i--) heapmodify(i);
    }
    vector<int> topKFrequent(vector<int>& nu, int k) {
        unordered_map<int,int> mp;
        for(int &x:nu) mp[x]++;
        for(auto p:mp)
        {
            if(q.size()<k) 
            {
                q.push_back({p.first,p.second});
                addnum();//持续维护堆性质
                //if(q.size()==k) build(k-1);  到K时建堆
            }
            else {
                if(q[0].se<p.second)
                {
                    q[0]={p.first,p.second};
                    heapmodify(0);
                }
            }
        }
        vector<int> res;
        for(auto & x:q) res.push_back(x.fi);
        return res;
    }
};

在这里插入图片描述

两个对顶堆维护第k个数

class MedianFinder {
public:
    vector<int> l;
    vector<int> r; 
    void heapmodifyback(vector<int> &nums,bool isbig) //添加数,自底向上更新
    {
        int len = nums.size() - 1,i=len;
        for (; (i - 1) >> 1 >= 0;)
        {
            int fa = (i - 1) >> 1;
            if (isbig)
            {
                if (nums[i] > nums[fa])
                {
                    swap(nums[i], nums[fa]);
                    i = fa;
                }
                else
                    break;
            }
            else {
                if (nums[i] < nums[fa])
                {
                    swap(nums[i], nums[fa]);
                    i = fa;
                }
                else
                    break;
            }
        }
    }
    void heapmodify(vector<int>& nums,int i,bool isbig){
        int n=nums.size()-1;
        for(;(i<<1)+1<=n;){
            int id=i;
            int lchild=(i<<1)+1;
            int rchild=(i<<1)+2;
            if(isbig)
            {
                if(lchild<=n&&nums[lchild]>nums[id]) id=lchild;
                if(rchild<=n&&nums[rchild]>nums[id]) id=rchild;
            }
            else {
                if(lchild<=n&&nums[lchild]<nums[id]) id=lchild;
                if(rchild<=n&&nums[rchild]<nums[id]) id=rchild;
            }
            if(id!=i){
                swap(nums[i],nums[id]);
                i=id;
            }
            else break;
        }
    } 
    void addNum(int num)
    {
        if (l.size() <= r.size())
        {
            if (l.size() && r[0] < num)
            {
                l.push_back(r[0]);
                heapmodifyback(l,1);
                r[0]=num;
                heapmodify(r,0,0);
            }
            else
            {
                l.push_back(num);
                heapmodifyback(l,1);
            }
        }
        else
        {
            if (l.size() && l[0] > num)
            {
                r.push_back(l[0]);
                heapmodifyback(r,0);
                l[0] = num;
                heapmodify(l, 0, 1);
            }
            else
            {
                r.push_back(num);
                heapmodifyback(r,0);
            }
        }
    }

    double findMedian()
    {

        if (l.size() == r.size())
            return (double)(l[0] + r[0]) * 0.5;
        else
            return l[0];
    }
};

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder* obj = new MedianFinder();
 * obj->addNum(num);
 * double param_2 = obj->findMedian();
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值