9.3-8 设X[1…n]和Y[1…n]为两个数组,每个都包含n个有序的元素,请设计一个O(lgn)O(lgn)O(lgn)时间的算法找出数组X和Y中所有2n个元素的中位数。

下面假设中位数(低中位数,数组长度偶数时较小的那个)在数组XXX中。如果要求中间两个数的均值,只需要在该基础之上修改一点就好。

a、X[k]=mX[k]=mX[k]=m为中位数,对于数组XXX,有kkk个元素小于等于X[k]X[k]X[k],同时有n−kn-kn−k个元素大于等于X[k]X[k]X[k]。当两个数组合并有序时,对于中位数来说,共有nnn个元素小于等于X[k]X[k]X[k],n个元素大于等于X[k]X[k]X[k]。那么对于数组YYY来说,有n−kn-kn−k个元素小于等于X[k]X[k]X[k],n−(n−k)=kn-(n-k)=kn−(n−k)=k个元素大于等于X[k]X[k]X[k]。那么就存在以下不等式:

Y[n−k]≤X[k]≤Y[n−k+1],1≤k&lt;nY[n-k] \leq X[k] \leq Y[n-k+1],1 \leq k &lt; nY[n−k]≤X[k]≤Y[n−k+1],1≤k<n

b、若X[k]若X[k]若X[k]不是中位数。且中位数为X[k′]&ThinSpace;(1≤k′&lt;k&lt;n)X[k'] \,(1 \leq k' &lt; k &lt; n)X[k′](1≤k′<k<n),那么就有:

Y[n−k′]≤X[k′]≤Y[n−k′+1]Y[n-k'] \leq X[k'] \leq Y[n-k'+1]Y[n−k′]≤X[k′]≤Y[n−k′+1]

那么对于X[k]X[k]X[k]来说,有:
Y[n−k+1]≤Y[n−k′]≤X[k′]&lt;X[k]Y[n−k+1]&lt;X[k]\begin{aligned} Y[n-k+1] &amp;\leq Y[n-k'] \leq X[k'] &lt; X[k] \\ Y[n-k+1] &amp;&lt; X[k] \end{aligned} Y[n−k+1]Y[n−k+1]​≤Y[n−k′]≤X[k′]<X[k]<X[k]​

c、若X[k]若X[k]若X[k]不是中位数。且中位数为X[k′](1≤k&lt;k′&lt;n)X[k'] \ (1 \leq k &lt; k' &lt; n)X[k′] (1≤k<k′<n),那么就有:
Y[n−k′]≤X[k′]≤Y[n−k′+1]Y[n-k'] \leq X[k'] \leq Y[n-k'+1]Y[n−k′]≤X[k′]≤Y[n−k′+1]

那么对于X[k]X[k]X[k]来说,有:
X[k]&lt;X[k′]≤Y[n−k′+1]≤Y[n−k]X[k]&lt;Y[n−k]\begin{aligned} X[k] &amp;&lt; X[k'] \leq Y[n-k'+1] \leq Y[n-k] \\ X[k] &amp;&lt; Y[n-k] \end{aligned} X[k]X[k]​<X[k′]≤Y[n−k′+1]≤Y[n−k]<Y[n−k]​

d、在递归的过程中,我们要注意一个递归的一个边界问题,在实际的编程中,对于数组A[L,..R],1≤L≤R≤nA[L,..R],1 \leq L \leq R \leq nA[L,..R],1≤L≤R≤n。我们取k=(L+R)/2,k∈[1,n]k=(L+R)/2,k \in [1,n]k=(L+R)/2,k∈[1,n], 当k=nk=nk=n时,那么对于上面三种情况会出现Y[n−k]=Y[0]Y[n-k]=Y[0]Y[n−k]=Y[0]是一个空数组,对于这种情况,其实只需判断X[k]=X[n]≤Y[1]X[k]=X[n] \leq Y[1]X[k]=X[n]≤Y[1]。

利用上面的性质,就可以在O(1)O(1)O(1)的时间内判断X[k]X[k]X[k]是否时中位数。对于一个数组区间X[L,R]X[L,R]X[L,R]。我们采用二分的思想,取中点k=(L+R)/2k=(L+R)/2k=(L+R)/2,判断上面的条件,如果满足条件a或d,那么X[k]X[k]X[k]就是中位数,如果是条件b,那么说明kkk偏大,我们在左子区间继续二分查找,否则为条件c,我们在右子区间继续二分查找。这样的一个二分查找过程的时间复杂度为Θ(lgn)\Theta(lgn)Θ(lgn)。

上面给出性质的是假设中位数在数组XXX的分析,如果中位数不在数组XXX中,在查找的过程中到达边界而不满足X[k]X[k]X[k]为中位数的a条件,我们可以返回一个标志如NOTFIND。此时中位数一定在数组YYY中,我们进行同样的操作。最差情况下进行2lgn2lgn2lgn次查找。时间复杂度仍为为Θ(lgn)\Theta(lgn)Θ(lgn)。

下面是伪代码:

Two-Array-Medium(X,Y)
n <-- X.length  //与数组Y长度相同
medium = Find-Medium(X,Y,1,n,n)//先尝试在数组X查找
if medium = NOTFIND//未找到,在Y数组查找medium = Find-Medium(Y,X,1,n,n)
return mediumFind-Medium(A,B,low,high,n)
if low > highreturn NOTFIND
elsek = (high+low)/2if k=n and A[n]<=B[1]return A[n]elseif k < n and B[n-k] <= A[k] <= B[n-k+1]return A[k]elseif B[n-k+1] < A[k]return Find-Medium(A,B,low,k-1,n)elsereturn Find-Medium(A,B,k+1,high,n)

实际编程中,数组从0开始稍微改动下即可。

#include<iostream>
#include<ctime>
#include<random>
#include<algorithm>
using namespace std;
#define LEN 5
#define NOTFIND 0x3f3f3f3f//参数n为数组长度,此时边界为n-1
int findMedium(int A[],int B[],int L,int R,int n)
{if(L>R)return NOTFIND;int k=(L+R)/2;// k=n-1时要独立一个分支,否则第二个if会越界if(k==(n-1)&&A[k]<=B[0])return A[k];else if(k<(n-1)&&B[n-k-2]<=A[k]&&A[k]<=B[n-k-1])return A[k];else if(B[n-k-1]<A[k])return findMedium(A,B,L,k-1,n);elsereturn findMedium(A,B,k+1,R,n);
}
int TwoArrayMedium(int A[],int B[],int len)
{int ret=NOTFIND;if((ret=findMedium(A,B,0,len-1,len))==NOTFIND)ret=findMedium(B,A,0,len-1,len);//不在数组A,继续在B中查找return ret;
}
template<typename T,unsigned N>
void getRandomArray(T (&arr)[N])
{//随机生成2000以内的随机数static default_random_engine e(time(nullptr));static uniform_int_distribution<T> d(0,2000);for(auto &i:arr)i=d(e);sort(arr,arr+N);//数组排序
}
int main()
{int A[LEN];int B[LEN];getRandomArray(A);getRandomArray(B);int C[2*LEN];copy(A,A+LEN,C);copy(B,B+LEN,C+LEN);sort(C,C+2*LEN);for(auto i:C)cout << i << " ";cout << endl;cout << "中位数为:" << TwoArrayMedium(A,B,LEN) << endl;return 0;
}

  这个问题我只求了低中位数,因为数组总长度为2n2n2n恒为偶数,因此如果要求中间两个数的均值。只需要在上面代码的基础上稍微改下,加上k+1k+1k+1位置的数,然后除2即可达到。(注意:如果k求出是X数组的最后一位,那么高中位数在数组Y中)

算法导论 练习9.3-8两个有序数组的中位数相关推荐

  1. 算法--------------------寻找两个有序数组的中位数

    题目描述 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2.请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)).你可以假设 nums1 和 num ...

  2. 6 js 比较两个数组的差异_每天一道算法题(js)(3)——寻找两个有序数组的中位数...

    给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和 nums2 ...

  3. python【力扣LeetCode算法题库】4- 寻找两个有序数组的中位数

    寻找两个有序数组的中位数 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 n ...

  4. 数组越界怎么判断_算法连载之求解两个有序数组的中位数

    问题 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2.找出这两个有序数组的中位数.假设 nums1 和 nums2 不会同时为空. 示例 1: nums1 = [1, 3] num ...

  5. 判断给定的两个数是否是亲和数_动画演示LeetCode算法题:004-寻找两个有序数组的中位数...

    题目: 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和 nu ...

  6. Leetcode算法题:两个有序数组求中位数

    Leetcode算法题:两个有序数组求中位数 要求时间复杂度为O(log(m+n)) 思路: 暴力解决:合并数组并排序,简单且一定能实现,时间复杂度O(m+n) 由于两个数组已经排好序,可一边排序一边 ...

  7. LeetCode实战:寻找两个有序数组的中位数

    题目英文 There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of th ...

  8. 4. 寻找两个有序数组的中位数

    给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和 nums2  ...

  9. leetcode 4. 寻找两个有序数组的中位数,c语言

    leetcode上第四道题,如下. 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2.请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)).你可以假 ...

  10. double 数组_寻找两个有序数组的中位数

    大家好,我是老皮: 题目地址:https://leetcode.com/problems/median-of-two-sorted-arrays/ 题目描述: 给定两个大小为 m 和 n 的有序数组 ...

最新文章

  1. 10种避免大型部署的方法
  2. oracle 修改数据表结构常用sql
  3. Linux命令大总结(早期学习时的笔记)
  4. MongoDB 4.2 内核解析 - Change Stream
  5. Springboot2.0 集成 Elasticsearch 6.x 未添加 transport-netty4-client 依赖 启动时报错
  6. 95-40-025-java.util.concurrent-并发容器
  7. 路由器太远手机接收不到信号怎么办?
  8. Python并发编程系列之多进程(multiprocessing)
  9. 为什么要使用Ruby的attr_accessor,attr_reader和attr_writer?
  10. Apache的用户认证、域名跳转、Apache的访问日志
  11. sp_executesq用法
  12. android shape自定义渐变,Android实现 Shape属性gradient 渐变效果
  13. HNU--计算机网络实验2
  14. LSTM中对time step的理解
  15. ThreadPool线程池原理
  16. 常用的Java Web框架简介
  17. SQLServer Job 邮件发送
  18. 买外链有没有影响?会导致网站降权吗?玉米社
  19. 阿里巴巴菜鸟网络二面
  20. mysql 禁用事件_mysql事件之修改事件(ALTER EVENT)、禁用事件(DISABLE)、启用事件(ENABLE)、事件重命名及数据库事件迁移操作详解...

热门文章

  1. PHP实现上传文件并存进数据库的方法
  2. Java_Spring MVC_Servlet
  3. 将多个文件绑在一起执行
  4. JPA多表查询映射自定义实体类(包含两个表字段)
  5. SpringMVC_跟踪请求
  6. automake的使用1
  7. 【C++快速入门】基础语法篇
  8. CMD下netstat ping等命令提示:不是内部或外部命令,也不是可运行的程序或批处理文件。
  9. 比特币所有权及隐私问题 | 转账的加密流程
  10. 读书笔记_中国期货市场量化交易(李尉)05