热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

程序员面试金典——解题总结:9.18高难度题18.9随机生成一些数字并传入某个方法。编写一个程序,每当收到新数字时,找出并记录中位数。

#include#include#include#include#includeusi

#include
#include
#include
#include
#include using namespace std;
/*
问题:随机生成一些数字并传入某个方法。编写一个程序,每当收到新数字时,找出并记录中位数。
分析&#xff1a;题目的意思应该是&#xff1a;根据随机生成了k个数字之后&#xff0c;接下来每次再收到新数字时&#xff0c;找到中位数。简化问题&#xff1a;寻找中位数&#xff0c;什么是中位数&#xff1f;就是数组A排序之后&#xff0c;假设共有n个数字&#xff0c;如果n为奇数&#xff0c;那么A[n/2]即为中位数如果n为偶数&#xff0c;那么A[n/2 - 1] , A[n/2 - 1]累加之后除以2。假设我事先对之前的随机生成的元素组成的数组A排序&#xff0c;不妨假设不管n为奇数或者偶数&#xff0c;寻找的中位数都是A[n/2]&#xff0c;那么我可以事先取出中间3个数A[n/2 - 1],A[n/2]&#xff0c;A[n/2&#43;1]然后用新生成的数字和A[n/2]比较&#xff0c;如果A[n/2] > 生成的数字&#xff0c;那么新的中位数直接就是A[n/2 - 1]如果A[n/2] <生成的数字&#xff0c; A[n/2 &#43; 1]&#61; A[n/2]书上解法&#xff1a;
用两个优先级堆&#xff0c;大顶堆&#xff1a;存放小于中位数的值&#xff0c;小顶堆&#xff1a;存放大于中位数的值。则大顶堆的对顶是最大值&#xff0c;小顶堆的对顶是最小值。
如果:大顶堆的大小 > 小顶堆的元素大小&#xff0c;则大顶堆的堆顶为中位数&#61; &#xff0c;则大小顶堆的平均值为中位数。
只需要使得大顶堆的大小>&#61;小顶堆的大小。
有新元素生成&#xff0c;如果 新元素 <&#61; 中位数&#xff0c;放入大顶堆(即包含较小元素的那一堆)&#xff1b;> 小
如果插入新元素后&#xff0c;大顶堆元素个数 >&#61; 小顶堆元素个数&#43;2&#xff0c;说明较小的那一堆元素个数多了&#xff0c;将大顶堆的对顶移动到小顶堆大顶堆元素个数 <小顶堆元素个数&#xff0c;将小顶堆的对顶移动到大顶堆输入&#xff1a;
4(初始元素个数)
1 4 7 10
3(后续生成的新元素个数)
3 2 8
输出:
4.00(后续第一个新元素加入后的中位数&#xff0c;保留两位小数)
3.50
4.00关键:
1
用两个优先级堆&#xff0c;大顶堆&#xff1a;存放小于中位数的值&#xff0c;小顶堆&#xff1a;存放大于中位数的值。则大顶堆的对顶是最大值&#xff0c;小顶堆的对顶是最小值。
如果:大顶堆的大小 > 小顶堆的元素大小&#xff0c;则大顶堆的堆顶为中位数&#61; &#xff0c;则大小顶堆的平均值为中位数。
只需要使得大顶堆的大小>&#61;小顶堆的大小。
有新元素生成&#xff0c;如果 新元素 <&#61; 中位数&#xff0c;放入大顶堆(即包含较小元素的那一堆)&#xff1b;> 小
如果插入新元素后&#xff0c;大顶堆元素个数 >&#61; 小顶堆元素个数&#43;2&#xff0c;说明较小的那一堆元素个数多了&#xff0c;将大顶堆的对顶移动到小顶堆大顶堆元素个数 <小顶堆元素个数&#xff0c;将小顶堆的对顶移动到大顶堆
*/
class CompareMax
{
public:bool operator()(const int a ,const int b)const{return a > b ? true : false;}
};class CompareMin
{
public:bool operator()(const int a ,const int b)const{return a };//利用初始的数组产生两个堆&#xff0c;大顶堆存放较小部分元素&#xff0c;小顶堆存放较大部分元素&#xff0c;且满足: 小顶堆元素个数<&#61; 大顶堆元素个数 <&#61; 小顶堆元素个数&#43;1
void generateSet(vector& datas , multiset& maxHeap , multiset& minHeap )
{if(datas.empty()){return;}//初始先排序sort(datas.begin() , datas.end());int size &#61; datas.size();int middleNum &#61; (size &#43; 1) / 2;//将前半段小的放入到大顶堆中for(int i &#61; 0 ; i }double getMiddleNum(multiset& maxHeap , multiset& minHeap )
{int minSize &#61; maxHeap.size();int maxSize &#61; minHeap.size();double originalMiddleNum &#61; 0;//计算原始中位数&#xff0c;如果总元素个数是奇数个&#xff0c;那么原始中位数等于大顶堆的堆顶if( ( (minSize &#43; maxSize) & 1 ) &#61;&#61; 1){originalMiddleNum &#61; *(maxHeap.begin());}else{originalMiddleNum &#61; ( *maxHeap.begin() &#43; *minHeap.begin() ) / 2.0;}return originalMiddleNum;
}//根据输入的新元素&#xff0c;大顶堆和小顶堆&#xff0c;生成中位数
double generateMiddleNum(int value, multiset& maxHeap , multiset& minHeap )
{double originalMiddleNum &#61; getMiddleNum(maxHeap , minHeap);//比较如果&#xff1a;新元素 <&#61; 原始中位数&#xff0c;则插入到大顶堆(即较小部分的那一堆元素中)if( 1.0*value <&#61; originalMiddleNum ){maxHeap.insert(value);}else{minHeap.insert(value);}//如果大顶堆元素个数 >&#61; 小顶堆元素个数 &#43; 2 ,就把大顶堆的堆顶移除&#xff0c;并插入到小顶堆中int minSize &#61; maxHeap.size();int maxSize &#61; minHeap.size();if( minSize >&#61; maxSize &#43; 2){int value &#61; *maxHeap.begin();maxHeap.erase(maxHeap.begin());minHeap.insert(value);}//如果大顶堆元素个数 <小顶堆元素个数&#xff0c;就把小顶堆的堆顶移除&#xff0c;并插入到大顶堆中else if(minSize }void process()
{int originalNum , addNum ;vector datas;vector newDatas;int value;multiset maxHeap;multiset minHeap;double middleNum;cout.setf(ios::fixed);cout.precision(2);while(cin >> originalNum ){datas.clear();newDatas.clear();maxHeap.clear();minHeap.clear();for(int i &#61; 0 ; i > value;datas.push_back(value);}//生成初始的大顶堆和小顶堆generateSet(datas , maxHeap , minHeap);cin >> addNum;for(int i &#61; 0 ; i > value;//接下来对每次新输入的元素&#xff0c;生成中位数middleNum &#61; generateMiddleNum(value , maxHeap , minHeap);cout <}int main(int argc , char* argv[])
{process();getchar();return 0;
}



推荐阅读
  • 题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ... [详细]
  • 本文详细探讨了KMP算法中next数组的构建及其应用,重点分析了未改良和改良后的next数组在字符串匹配中的作用。通过具体实例和代码实现,帮助读者更好地理解KMP算法的核心原理。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本题探讨了一种字符串变换方法,旨在判断两个给定的字符串是否可以通过特定的字母替换和位置交换操作相互转换。核心在于找到这些变换中的不变量,从而确定转换的可能性。 ... [详细]
  • 在 Windows 10 中,F1 至 F12 键默认设置为快捷功能键。本文将介绍几种有效方法来禁用这些快捷键,并恢复其标准功能键的作用。请注意,部分笔记本电脑的快捷键可能无法完全关闭。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
  • 本文基于刘洪波老师的《英文词根词缀精讲》,深入探讨了多个重要词根词缀的起源及其相关词汇,帮助读者更好地理解和记忆英语单词。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • Python 异步编程:深入理解 asyncio 库(上)
    本文介绍了 Python 3.4 版本引入的标准库 asyncio,该库为异步 IO 提供了强大的支持。我们将探讨为什么需要 asyncio,以及它如何简化并发编程的复杂性,并详细介绍其核心概念和使用方法。 ... [详细]
  • 本文详细记录了在基于Debian的Deepin 20操作系统上安装MySQL 5.7的具体步骤,包括软件包的选择、依赖项的处理及远程访问权限的配置。 ... [详细]
  • 资源推荐 | TensorFlow官方中文教程助力英语非母语者学习
    来源:机器之心。本文详细介绍了TensorFlow官方提供的中文版教程和指南,帮助开发者更好地理解和应用这一强大的开源机器学习平台。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
author-avatar
诗雨妈咪201101102002
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有