相关问题:

设 x[1..n]和Y[1..n]为两个数组,每个都包含n个已排序的数。给出一个求数组X和Y中所有2n个元素的中位数的O(lgn)时间的算法。

思考过程:

开始我想把两个数组X与Y放入到一个数组Z中,对Z进行排序,这样Z的中位数易求。但是有2点原因使得这种做法不可行,1.是将2数组放入到1个数组中的过程会产生O(n)的时间,所以不满足题意。2如果对新数组Z排序,那么最少需要线性O(n)时间进行排序,也不满足O(lgn)这个时间的需求。然后我又试图用最坏时间线性选择子程序,但是马上想到,这样就是O(n),不是O(lgn)的时间了,所以用不上书中9.3节的内容。

后来我想到如果要想达到O(lgn)这个数量级的查找,那么可以选择二分法进行查找,首先判断数组X(Y)是否所有数都小于数组Y(X),如果假设成立,那么直接返回数组X最后一个数即可。如果集合X与Y之中的数存在集合X的某元素<集合Y的某元素,同时集合X的某元素>集合Y的某元素,那么进入递归。具体递归过程请见代码注释。(PS:其实我认为这个问题就是考察对二分法的灵活运用。)

具体步骤

开始随机化数组,然后对数组进行排序。因为原题的意思是要想进行O(lgn)时间的选择,那么前提是两数组已排序,所以不能将排序过程算在总的选择时间里面。当然你也可以选择自己设置数组元素值,使其初始化时便已有序。

Two_groups_array_Median函数具体步骤是:

step 1:判断数组X(Y)所有数是否均小于数组Y(X)所有数。如果小于,则直接返回中位数。程序立即结束。

step 2:判断数组X与Y,begin项≥end项?如果成立,则进入最后的微调与返回中位数阶段。

step 3:如果step 1,2都不成立,那么进入二分法的递归过程。具体过程见代码注释。

#include <iostream>
#include <time.h>
using namespace std;
const n=25;
void INSERTION_SORT(int A[],int r)//利用任意一个排序算法设置数组为题目条件“有序”。
{int key;for (int j=1;j<=r;j++){key=A[j-1];int i=j-1;while (i>0&&A[i-1]>key)//a)插入排序时间复杂度O(n^2)对于长度为k的子列表都有O(k^2),则n/k个为(k^2)*n/k=O(nk){A[i]=A[i-1];i=i-1;}A[i]=key;}
}
void Initialization(int A[],int r,int a,int b)//初始化数组
{srand( (unsigned)time( NULL ) );for (int i=0;i<n;i++){A[i]=rand()%(a-b+1)+b;}
}
void Print(int A[],int r)
{for (int i=0;i<r;i++){cout<<A[i]<<" ";}cout<<endl;
}
int Two_groups_array_Median(int A[],int B[],int beginA,int endA,int beginB,int endB)
{int p=(beginA+endA)/2;int r=(beginB+endB)/2;int t=p+r+2,flag=0;//经过大量的实验证明(我试图用数学归纳法证明,惭愧的是我没有完整证明出来,如果有大牛觉的我的这个结论是错误的,那么可以举反例证明我的错误以待我去改正,小弟在此先感谢纠正我错误给我留言的人):t≈n 最多相差常数个误差。误差产生的原因是p和r定义时除以2后,全部向下取整了,而精确的中位数是需要有时向上取整的。//t表示当前中位数p和r前面有多少个元素,由于数组下标是从0开始的,所以需要+上A[0]和B[0]。if (A[n-1]<B[0])//如果集合A与B之中的某一集合所有的数均小于另外一集合所有数,则直接返回较小数组的最后一位即为中位数{return A[n-1];}else if (A[0]>B[n-1]){return B[n-1];}if (beginA>=endA||beginB>=endB)//如果A与B哪个先递归到begin项≥end项,那么就进行下面的判断。{if (n-t>0){for (int i=1;i<=n-t;i++)//对于上面注释所说的误差所差常数的具体数值,根据这个常数数值再求精确的中位数,否则如果没有这个循环,那么所求中位数与真实中位数要相差常数个位置{++p;++r;if (A[p]<B[r]){--r;flag=1;}else {--p;flag=0;}}if (flag)//这个if-else语句是要返回A与B中较小的那个数,较小的数就是中位数。{return A[p];}else{return B[r];}}else//如果n=t,无需进行微调,由于p+r+2正好等于这2n个数的中间值下标n,那么就返回较大值,较大值正好是第n个数。{if (A[p]<B[r]){return B[r];}else{return A[p];}}}if (A[p]>B[r])//如果数组A的中位数大于数组B的中位数,那么两数组的中位数必在数组A当前中位数的左边,数组B当前中位数的右边{return Two_groups_array_Median(A,B,beginA,p,r,endB);//对数组A的左半部分数组B的右半部分进行递归。}else //小于情况类似,这里不做累述。{return Two_groups_array_Median(A,B,p,endA,beginB,r);}
}
void main()
{int A[n]={0},B[n]={0};cout<<"随机数组A初始化。。。"<<endl;Initialization(A,n,10000,9);INSERTION_SORT(A,n);//利用插入排序设置数组使其变为题目所说的“已排序”的数组。Print(A,n);cout<<"随机数组B初始化。。。"<<endl;Initialization(B,n,15000,1000);INSERTION_SORT(B,n);Print(B,n);cout<<"两数组中位数="<<Two_groups_array_Median(A,B,0,n-1,0,n-1)<<endl;
}

用O(lgn)时间求出两个已排序数组的中位数相关推荐

  1. 0009 求出两个数的正差值

    // 名称:0009 求出两个数的正差值 // 作者:丁进 // 时间:2021.2.14 #include <stdio.h> //第一种方法:根据比较结果,直接输出大值减小值的差 in ...

  2. c编程:求出4#215;4矩阵中最大和最小元素值及其所在行下标和列下标,求出两条主对角线元素之和。...

    //求出4×4矩阵中最大和最小元素值及其所在行下标和列下标,求出两条主对角线元素之和 #include <stdio.h> int main() {int sum=0;int max,mi ...

  3. 利用函数求出两个数的最大值

    利用函数,求出两个数的最大值,要求可以自己输入数值,并且利用函数 例如 a=10 b=20 最后的结果为20 函数段 int MAX(int x, int y) {int z = 0;if (x &g ...

  4. matlab怎么求两个数的和,matlab怎么求出两个函数的交点

    matlab中,两个自变量的函数怎么求最大值(急!1) 需求:利用matlab求解二元函数y=f(x1,x2)=(339-0.01*x1-0.003*x2)*x1+(399-0.004*x1-0.01 ...

  5. PHP求1到100所有偶数的和,php求出两数之间所有偶数之和

    定义Show类 类中定义方法 sum 方法中传入两个数 在方法体内部求出两个数之间所有偶数得和 将求出得结果返回 输出返回后的结果 输出形式如下 两个数之间所有偶数得和为: 30 注意判断:传入得两个 ...

  6. leetcode题库:4.两个排序数组的中位数

    题目: /**   *leetcode题库:4. 求两个排序数组的中位数  *  *  给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 .  *  请找出这两个有序数组的中位数. ...

  7. LeetCode 4 两个排序数组的中位数

    有两个大小为 m 和 n 的排序数组 nums1 和 nums2 . 请找出两个排序数组的中位数并且总的运行时间复杂度为 O(log (m+n)) . 示例 1: nums1 = [1, 3] num ...

  8. Leetcode4---求两个排序数组的中位数

    题目:给定两个排序数组,求两个排序数组的中位数,要求时间复杂度为O(log(m+n)) 举例: Example 1: nums1 = [1, 3] nums2 = [2]The median is 2 ...

  9. 算法-两个排序数组的中位数

    题目 两个排序数组的中位数 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 . 请找出这两个有序数组的中位数.要求算法的时间复杂度为 O(log (m+n)) . 示例 1:num ...

  10. 两个排序数组的中位数(4.Median of Two Sorted Arrays)

    题目: 有两个排序的数组nums1和nums2分别为m和n大小. 找到两个排序数组的中位数.整体运行时间复杂度应为O(log(m + n)). 示例1: nums1 = [1,3] nums2 = [ ...

最新文章

  1. Linux系统中的软件管理
  2. 数据结构树的基本操作_《数据结构》树的基本操作.doc
  3. python登录接口代码_(转载)Python 的 OAuth 登录接口 python-oauth2
  4. iOS imageio nsurlsession 渐进式图片下载
  5. python打印生成word_使用python调用zabbix接口截取监控图并生成Word文档
  6. 计算SDWebImage缓存大小以及清除
  7. uniapp 开发h5 优化加载速度
  8. xMind思维导图软件如何合并多个导图
  9. java图像处理002---JAVA图片压缩_图片缩放_图片按照比例缩放_图片指定长宽缩放_Java使用google开源工具Thumbnailator实现图片压缩
  10. window.location.href如何多次请求_测试同学必会系列之如何进行幂等性的测试
  11. word图片居中, 实际没效果解决、行间距无效果
  12. 猫、路由器、交换机的区别
  13. linux添加jetdirect协议,《HP jetdirect 管理指南》教程.pdf
  14. [渝粤教育] 新乡医学院 医学微生物学 参考 资料
  15. CookGAN Causality based Text-to-Image Synthesis
  16. java或android国内外手机号码正则表达式
  17. matlab 指数分布检验,如何使用Matlab检验数据服从什么分布
  18. 每周全球科技十大新闻(2021.1.18-1.24)
  19. 【JoJo的摄影笔记】相机分类新约
  20. AI Earth 开发者模式—— 如何加载影像?以Landsat 5 影像为例

热门文章

  1. 10.29 逻辑回归和交差熵
  2. 软件项目管理(复习)
  3. VC操作Word书签模板
  4. web前端开发常用的几种图片格式及其使用规范
  5. Mac下phpstorm 浏览器出现 502 bad gateway 解决办法
  6. 国内硕士申请加拿大计算机博士难度,【经验分享】如何申请加拿大硕士研究生或者博士?...
  7. 字节跳动8年经验,亲身经历教你如何从小白晋升月薪过万的测试工程师
  8. 这样来理解委托,代理,协议三者的区别
  9. 《SEM长尾搜索营销策略解密》一一2.7 经济基础决定上层建筑,文化也是
  10. 业务流程图和数据流程图、流程图