C语言 | Leetcode C语言题解之第295题数据流的中位数

news2024/11/22 22:34:56

题目:

题解:

typedef struct Heap
{
    int* array;   //存放堆的数组
    int  capacity;//数组的容量
    int  len;     //已存数组的大小
}Heap;
                                                        /*大小根堆切换开关*/
int  HeapLen(Heap* hp);                                 //heap获取当前的堆大小
void HeapSwap(int* pLeft, int* pRight);                 //heap交换父子结点的数值
bool HeapEmpty(Heap* hp);                               //heap判空
bool HeapFull(Heap* hp);                                //heap判满
int  HeapGetTop(Heap* hp);                              //heap获取堆顶
void HeapInsert(Heap* hp, int  dat,bool isMax);         //heap向堆的尾部插入1个元素
void HeapDelete(Heap* hp,bool isMax);                    //heap删除堆顶
void HeapAdjustDown(Heap* hp, int parent,bool isMax);   //heap向下调整
void HeapAdjustUp(Heap* hp, int child,bool isMax);      //heap向上调整
Heap* CreateHeap(int size);                             //heap创建
void heapFree(Heap* hp);                                //heap释放空间

int HeapLen(Heap* hp)
{
    return hp->len;
}

bool HeapEmpty(Heap* hp)          //判空
{
    if (HeapLen(hp) == 1)
    {
        return true;
    }
    return false;
}

bool HeapFull(Heap* hp)          //判满
{
    if (hp->capacity == hp->len)
    {
        return true;
    }
    return false;
}


void HeapSwap(int* pLeft, int* pRight)//交换数值
{
    //交换堆中的父子结点
    int  temp;
    temp    = *pLeft;
    *pLeft  = *pRight;
    *pRight = temp;
}

int HeapGetTop(Heap* hp)
{
    return hp->array[1];
}



Heap* CreateHeap(int size)
{
    Heap* heap = (Heap*)malloc(sizeof(Heap));
    int   heapLen = size + 1;//长度比size的长度大1才行
    //给堆申请空间,初始化
    heap->array = (int*)malloc(sizeof(int) * heapLen);
    heap->capacity  = heapLen;     //容量
    heap->len       = 1;           //当前大小
    return heap;
}

void HeapAdjustDown(Heap* hp, int parent ,bool isMax)//向下调整
{
    //标记左右孩子中最小孩子
    int child = 2 * parent;            //左孩子为2*parent  右孩子为 2*parent +1
    int len  = hp->len;
    while (child < len)
    {
        if(isMax)
        {
            //大根堆 选最大的
            //有右子树时 ,找左右孩子中最大的孩子 
            if ((child + 1 < len) && hp->array[child] < hp->array[child + 1])
                child = child + 1;

            //最大孩子大于双亲时 ,孩子与双亲数值交换,否则说明已经调好,不用继续
            if (hp->array[child] > hp->array[parent])
            {
                HeapSwap(&hp->array[child], &hp->array[parent]);
                parent = child;
                child = parent << 1;
            }
            else
                return;
        }
        else
        {
            //小根堆  选最小的
            //有右子树时 ,找左右孩子中最小的孩子 
            if ((child + 1 < len) && hp->array[child] > hp->array[child + 1])
                child = child + 1;

            //最小孩子小于双亲时 ,孩子与双亲数值交换,否则说明已经调好,不用继续
            if (hp->array[child] < hp->array[parent])
            {
                HeapSwap(&hp->array[child], &hp->array[parent]);
                parent = child;
                child = parent << 1;
            }
            else
                return;
        }
    }
}




void HeapAdjustUp(Heap* hp, int child,bool isMax)//向上调整
{
    //得到父母结点的位置
    int parent = child / 2;
    while (child > 1)
    {
        if(isMax)
        {
            //大根堆选择大的
            //循环迭代从child当前位置一直迭代到0位置即对顶
            if (hp->array[child] > hp->array[parent])
            {
                HeapSwap(&hp->array[child], &hp->array[parent]);
                child = parent;
                parent = child/2;
            }
            else
                return;
        }
        else
        {
            //小根堆选择小的
            //循环迭代从child当前位置一直迭代到0位置即对顶
            if (hp->array[child] < hp->array[parent])
            {
                HeapSwap(&hp->array[child], &hp->array[parent]);
                child = parent;
                parent = child/2;
            }
            else
                return;
        }
    }
}

void HeapDelete(Heap* hp,bool isMax)//删除堆顶
{
    if (HeapEmpty(hp))
        return;

    //用最后一个元素覆盖堆顶,相当于删除堆顶
    hp->array[1] = hp->array[hp->len - 1];
    hp->len--;//删除最后一个元素 heap长度变短
    HeapAdjustDown(hp, 1,isMax);//对第一个元素进行调整
}



void HeapInsert(Heap* hp, int  dat,bool isMax)
{
    if (HeapFull(hp))
    {
        //扩容
        hp->capacity <<= 1; 
        hp->array = (int *) realloc(hp->array, hp->capacity * sizeof(int));
    }
    int child = 0;
    int parent = 0;
    //插入到最后一个元素的下一个位置
    hp->array[hp->len++] = dat;
    //调整刚插入元素,
    //因为插入的是堆的尾部,需要堆向上调整
    HeapAdjustUp(hp, hp->len - 1,isMax);
}


void heapFree(Heap* hp)
{
    free(hp->array);
    free(hp);
}

typedef struct 
{
    //左边是 最大堆   右边是小根堆
    //0 1 3              5 7 9 
    Heap* maxLHeap;
    Heap* minRHeap; 
} MedianFinder;


MedianFinder* medianFinderCreate() 
{
    MedianFinder* newMedian = (MedianFinder* )malloc(sizeof(MedianFinder));
    newMedian->maxLHeap = CreateHeap(128);
    newMedian->minRHeap = CreateHeap(128);
    return newMedian;
}

void medianFinderAddNum(MedianFinder* obj, int num)
{
    //检查
    int leftHeapLen = obj->maxLHeap->len;
    int rightHeapLen = obj->minRHeap->len;

    if (leftHeapLen <= rightHeapLen)
    {
        //插入左边的最小堆


        //检查当前值 是否大于 右边的最小堆的堆顶值
        if (!HeapEmpty(obj->minRHeap))
        {
            if (num > obj->minRHeap->array[1])
            {
                //保存当前右边最小堆堆顶值 需要准备移动到 左边 最大堆中
                int  moveValue = obj->minRHeap->array[1];

                //将当前值放到 右边的最小堆 的堆顶
                obj->minRHeap->array[1] = num;
                HeapAdjustDown(obj->minRHeap, 1, false);

                //插入到左边最大堆中
                HeapInsert(obj->maxLHeap, moveValue, true);

                //直接结束了
                return;
            }
        }

        //这里检查 num是小于右边的 最小堆 的堆顶值的
        HeapInsert(obj->maxLHeap, num, true);
    }
    else
    {
        //插入右边的最大堆


        //检查当前值 是否小于 左边的最大堆的堆顶值
        if (!HeapEmpty(obj->maxLHeap))
        {
            if (num < obj->maxLHeap->array[1])
            {
                //保存当前左边最大堆堆顶值 需要准备移动到 右边 最小堆中
                int  moveValue = obj->maxLHeap->array[1];

                //将当前值放到 左边的最da堆 的堆顶
                obj->maxLHeap->array[1] = num;
                HeapAdjustDown(obj->maxLHeap, 1, true);

                //插入到右边最小堆中
                HeapInsert(obj->minRHeap, moveValue, false);

                //直接结束了
                return;
            }
        }
        //这里检查 num是大于左边的 最大堆 的堆顶值的
        HeapInsert(obj->minRHeap, num, false);
    }


}

double medianFinderFindMedian(MedianFinder* obj)
{
    if (obj->maxLHeap->len == obj->minRHeap->len)
    {
        return (double)(obj->minRHeap->array[1] + obj->maxLHeap->array[1]) / 2;
    }

    return (double)obj->maxLHeap->array[1];

}

void medianFinderFree(MedianFinder* obj) 
{
    heapFree(obj->maxLHeap);
    heapFree(obj->minRHeap);
    free(obj);
}

/**
 * Your MedianFinder struct will be instantiated and called as such:
 * MedianFinder* obj = medianFinderCreate();
 * medianFinderAddNum(obj, num);
 
 * double param_2 = medianFinderFindMedian(obj);
 
 * medianFinderFree(obj);
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1951719.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安装VMware Workstation Pro

一、下载 通过百度网盘分享的文件&#xff1a;VMware-workstation-full-16.2.4-2008... 链接&#xff1a;https://pan.baidu.com/s/1mDnFhLQErBlpeX_KjsgtzA 提取码&#xff1a;0bw7 二、安装 &#xff08;1&#xff09;双击exe文件 &#xff08;2&#xff09;安装软件 &…

本地部署Graphhopper路径规划服务(graphhopper.sh启动版)

文章目录 文章参考源码获取一、配置Java环境变量二、配置Maven环境变量三、构建graphhopper步骤1. 下载数据2. 配置graphhopper配置文件config-example.yml3. 在项目中启动命令行执行./graphhopper.sh build3.1|、遇到的问题3.1.1、pom.xml中front-maven-plugin-无法下载npm6.1…

结构型设计模式-组合模式

一、组合模式 对于这个图片肯定会非常熟悉&#xff0c;上图我们可以看做是一个文件系统&#xff0c;对于这样的结构我们称之为树形结构。在树形结构中可以通过调用某个方法来遍历整个树&#xff0c;当我们找到某个叶子节点后&#xff0c;就可以对叶子节点进行相关的操作。可以将…

Python安装库太慢?配置好这个速度飞起

经常听到初学python的小伙伴在抱怨&#xff0c;python安装第三方库太慢&#xff0c;很容易失败报错&#xff0c;如果安装pandas、tensorflow这种体积大的库&#xff0c;简直龟速。 为什么pip会很慢&#xff1f; 先来了解下pip&#xff0c;pip是一个非常流行的python包管理工具…

【苍穹】完美解决由于nginx更换端口号导致无法使用Websocket

一、报错信息 进行到websocket开发的过程中&#xff0c;遇到了前端报错&#xff0c;无法连接的提示&#xff1a; 经过F12排查很明显是服务端和客户端并没有连接成功。这里就涉及到之前的坑&#xff0c;现在需要填上了。 二、报错原因和推导 应该还记得刚开苍穹的第一天配置前…

技术实践—微前端技术应用

微前端是一种新兴的前端架构模式&#xff0c;是一种类似于微服务的架构&#xff0c;将微服务的理念应用于浏览器端。其核心理念是将一个大而单一的前端应用拆分为多个小型独立的微应用。这些微应用各自独立&#xff0c;可以由不同团队开发维护&#xff0c;部署&#xff0c;组合…

docker发布镜像到自己远程私有仓库

1、登录docker hub创建自己的仓库地址&#xff1a;https://hub.docker.com/repository/create 输入仓库名称 2.构建镜像 略过。。。。请自己查找别的资料&#xff0c;此篇文章只讲述镜像推送到远程 3.推送 假设你已经构建了一个镜像 web/online-editor:latest&#xff0c;现…

【React学习打卡第二天】

受控表单绑定、React获取Dom\组件通信、useEffect、自定义hook函数和ReactHooks使用规则 一、受控表单绑定1.准备React状态值2.通过value属性绑定状态&#xff0c;通过onChange属性绑定状态同步的函数 二、React中获取DOM1. 使用useRef创建 ref 对象&#xff0c;并与 JSX 绑定2…

使用图数据库Nebula Graph快速上手史上最大规模的中文知识图谱ownthink_v2教程(没写完,明天再写)

一、前言 本教程主要参考官方教程&#xff1a;使用图数据库 Nebula Graph 数据导入快速体验知识图谱 OwnThink (nebula-graph.com.cn) 来带着大家一步一步复现实验内容。 本教程主要使用到的数据集&#xff1a; ownthink/KnowledgeGraphData: 史上最大规模1.4亿中文知识图谱…

MySQL 存储

关系型数据库是基于关系模型的数据库&#xff0c; 而关系模型是通过二维表来保存的&#xff0c;所以关系型数据库中的数据的村方式就是行列组成的表&#xff0c;每一列代表一个字段&#xff0c;每一行代表一条记录。表可以看作某个实体的集合&#xff0c;实体之间存在的联系需要…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第五十三章 设备树下的platform驱动

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

基于开源大模型的问答系统本地部署实战教程

1. 现有大模型产品使用感受 在开始教你搭建属于自己的本地大模型之前&#xff0c;先说下自己日常使用大模型的感受。常用的比较好的国外大模型工具&#xff0c;经常会遇到网络卡或者token数量、使用次数限制的问题。而国内的大模型工具虽然不存在网络的问题&#xff0c;但…

简单几步,教你使用scikit-learn做分类和回归预测

经常听到初学python的小伙伴在抱怨&#xff0c;python安装第三方库太慢&#xff0c;很容易失败报错&#xff0c;如果安装pandas、tensorflow这种体积大的库&#xff0c;简直龟速。 为什么pip会很慢&#xff1f; 先来了解下pip&#xff0c;pip是一个非常流行的python包管理工具…

基于微信小程序+SpringBoot+Vue的资料分享系统(带1w+文档)

基于微信小程序SpringBootVue的资料分享系统(带1w文档) 基于微信小程序SpringBootVue的资料分享系统(带1w文档) 校园资料分享微信小程序可以实现论坛管理&#xff0c;教师管理&#xff0c;公告信息管理&#xff0c;文件信息管理&#xff0c;文件收藏管理等功能。该系统采用了Sp…

初识C++ · AVL树(2)

目录 前言&#xff1a; 1 左右旋 2 右左旋 3 部分细节补充 3.1 单旋和插入 3.2 部分小函数 前言&#xff1a; AVL树作为一种结构&#xff0c;理解树的本身是不大难的&#xff0c;难的在于&#xff0c;树旋转之后的连接问题&#xff0c;写AVL树的代码大部分都是在旋转部分…

在jeesite开源平台上写了一个SQL命令中心的功能

实现目的: 这个SQL命令中心,是因为老项目就有这个页面,主要的功能是根据写出的SQL语句查询数据,并且在查出的数据基础上直接修改更新,还有新增和删除的功能,这么一说跟plsql就一样一样的了;这页面本来是给运维的同事来用,而且他们还会用plsql和Navicat等SQL语言操作工…

[OJ]平均串问题,存在超时问题未解决

众所周知&#xff0c;两个数a和b的平均数计算公式为(ab)/2。 实际上平均数也可以描述为&#xff1a;从较小的数依次遍历到较大的数&#xff0c;将遍历的数放入一个列表中&#xff0c;该列表的中心元素。例如&#xff1a;求 3和7的平均数&#xff0c;列表为{3,4,5,6,7}&#xff…

FPGA与ASIC:深入解析芯片设计的双子星

前言 在半导体世界里&#xff0c;FPGA&#xff08;Field-Programmable Gate Array&#xff0c;现场可编程门阵列&#xff09;与ASIC&#xff08;Application-Specific Integrated Circuit&#xff0c;专用集成电路&#xff09;是两种截然不同的芯片设计策略&#xff0c;各自在…

短视频矩阵系统,一键智能成片

在信息爆炸的时代&#xff0c;短视频以其短平快的特点迅速崛起&#xff0c;成为人们获取信息、娱乐消遣的重要渠道。然而&#xff0c;如何在这个竞争激烈的领域中脱颖而出&#xff0c;制作出吸引眼球的爆款视频呢&#xff1f;今天&#xff0c;我们就来揭秘一款神奇的短视频矩阵…

76.WEB渗透测试-信息收集- WAF、框架组件识别(16)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;75.WEB渗透测试-信息收集- WAF、框架组件识别&#xff08;15&#xff09; Php的Laraverl…