首页 > 其他分享 >LeetCode双堆问题

LeetCode双堆问题

时间:2022-10-07 11:45:47浏览次数:87  
标签:双堆 vector curs int 问题 num heap data LeetCode

Find Median from Data Stream

LeetCode/力扣

数组保存数据,add的时候直接在末尾插入,查找的时候,先排序,然后再算其中的结果

vector<int> data;
/** initialize your data structure here. */
MedianFinder() {
    
}

void addNum(int num) {
    data.push_back(num);
}

double findMedian() {
    sort(data.begin(), data.end());
    
    int n = data.size();
    if(n % 2 == 1) {
        return data[(n) / 2];
    }else {
        return (data[n/2] + data[(n/2) - 1]) * 0.5;
    }
}

上述方案应该过不了案例,插入的时候用二分查找,先找到要插入的位置,然后直接插入,find的时候直接计算就可以了

vector<int> data;

void addNum(int num){
    if(data.empty()){
        data.push_back(num);
    }else {
        data.insert(lower_bound(data.begin(),data.end(), num), num); // 二分查找到应该插入的位置
    }
}

double findMedian() {        
    int n = data.size();
    if(n % 2 == 1) {
        return data[(n) / 2];
    }else {
        return (data[n/2] + data[(n/2) - 1]) * 0.5;
    }
}

二叉堆,可以用两个stl的优先队列(内部是用二叉堆)来维护,一个队列是最大堆,一个队列是最小堆,最大堆保存的是小半部分的数字,最小堆保存的是大半部分的数字,这样队首的和就是中位数了

priority_queue<int, vector<int>, less<int>> max_heap;
priority_queue<int, vector<int>, greater<int>> min_heap;

void addNum(int num){
    max_heap.push(num);
    min_heap.push(max_heap.top());
    max_heap.pop();
    
    if(max_heap.size() < min_heap.size()){
        max_heap.push(min_heap.top());
        min_heap.pop();
    }
}

double findMedian() {
    return max_heap.size() > min_heap.size() ? max_heap.top() : (max_heap.top() + min_heap.top()) * 0.5;
}

sliding window median

LeetCode/力扣

将k中的数字用vector保存,分别定义add,del和find方法,分别表示添加和删除元素,以及查找中位数

vector<double> medianSlidingWindow(vector<int>& nums, int k) {
    vector<int> curs;
    vector<double> res;
    for(int i = 0; i < k; i++){
        add(curs, nums[i]);
    }
    res.push_back(find(curs));
    for(int i = k; i < nums.size(); i++){
        cout << "hi";
        del(curs, nums[i - k]);
        add(curs, nums[i]);
        res.push_back(find(curs));
    }
    return res;
}

double find(vector<int>& curs){
    int n = curs.size();
    if(n % 2 == 1){
        return curs[n / 2];
    }else{
        return curs[n / 2] /2.0 + curs[n / 2 - 1] / 2.0;
    }
}
void add(vector<int>& curs, int num){
    if(curs.empty()){
        curs.push_back(num);
    }else{
        curs.insert(lower_bound(curs.begin(), curs.end(), num), num);
    }
}
void del(vector<int>& curs, int num){
    curs.erase(lower_bound(curs.begin(), curs.end(), num));
}

用multiset来保存当前的数组,这是当前第一名的那个解法

vector<double> medianSlidingWindow(vector<int>& nums, int k) {
    vector<double> res;
    multiset<double> ms(nums.begin(), nums.begin() + k);
    auto mid = next(ms.begin(), k /  2);
    for (int i = k; ; ++i) {
        res.push_back((*mid + *prev(mid,  1 - k % 2)) / 2);        
        if (i == nums.size()) return res;
        ms.insert(nums[i]);
        if (nums[i] < *mid) --mid;
        if (nums[i - k] <= *mid) ++mid;
        ms.erase(ms.lower_bound(nums[i - k]));
    }
    
    return res;
}

标签:双堆,vector,curs,int,问题,num,heap,data,LeetCode
From: https://www.cnblogs.com/xnzone/p/16759360.html

相关文章

  • LeetCode二分搜索
    SearchinRotatedSortedArrayLeetCode/力扣先判断中间的和尾部的数字大小,再判断target和首尾中三个数字大小关系,如此便能进行二分搜索intsearch(vector<int>&nums,......
  • mongo docker 内存问题
    mongodocker镜像对于cgroup的内存管理是有点问题的,所以推荐基于容器运行mongo的配置上wiredTigerCacheSizeGB的大小可以规避内存占用的问题(同时最好做好内存限制)服......
  • 一次nginx 请求真实ip 问题处理
    nginxngx_http_realip模块是比较重要的,我以前也大概说过,同时网上关于此模块的资料也不少,今天就碰到了一个获取真实ip的问题记录下参考业务模型  问题以前的配置,waf......
  • 【Python】【爬虫】爬虫问题:requests的content和text
    爬虫问题:requests的content和text通常来说,text获取的是Unicode编码的文本数据,content获取的是byte类型的二进制数据,比如获取图片本身、PDF文件之类的,可以用content。但是......
  • 夯实Java基础,一篇文章全解析线程问题
    1\.线程是什么操作系统支持多个应用程序并发执行,每个应用程序至少对应一个进程,彼此之间的操作和数据不受干扰,彼此通信一般采用管道通信、消息队列、共享内存等方式。当一......
  • 隔板法解决小球放入箱子问题(箱子可空,箱子不可空)
    n个箱子k个小球1、不可空:k个小球共有k-1个空隙,k-1个空隙中选n-1个位置放入隔板,形成n个箱子答案为C(k-1,n-1)2、可空k个小球和n-1个隔板,选取k个位置放小球,并形成n个箱......
  • 解决MacPro谷歌浏览器右键翻译成中文无效问题
    对于Mac系统来说,Hosts文件位于/etc/hosts。在应用程序里面打开终端(terminal),输入如下命令:sudovi/etc/hosts然后使用vi编辑器添加下面一行,修改保存文件。203.208.......
  • Java 面试题 11 - 分布式系统常见问题
    分布式ID的实现分布式ID需要满足哪些需求?基本需求:全局唯一高性能:生成速度快,对本地资源消耗小。高可用:生成分布式ID的服务要保证高可用性。方便易用:使用方便......
  • LeetCode20 有效的括号
    给定一个只包括'(',')','{','}','[',']' 的字符串s,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都......
  • LeetCode138 复制带随机指针的链表
     idea: 刚开始没有思路,被题目弄懵了,我能想到的方法就是先复制不带random指针的链表,之后由表头到表尾再将每个结点的random指针通过循环进行连接,时间复杂度肯定时很高......