2,4,6,8,11,13,15,17,19,20
可以推出题目的一个隐含条件:偶数个元素的中位数是靠前的那一个
应试技巧:如果实在想不出高效的算法,那么就把笨办法写上,不能空卷
注意读题:是两个等长数组
奇数个元素的时候,只能删除中位数之前的
当a=b时,中位数=a=b
A:2,6,8,10,11
B:3,5,8,12,13
排序:2,3,5,6,8,8,10,11,12,13
当a<b时,a=8,b=10
假设A,B如下
A:2,6,8,10,11
B:3,5,10,13,15
A删除中位数左边的,B删除中位数右边的
A:8,10,11
B:3,5,10
此时a=10,b=5,a>b,A删除中位数右边的,B删除中位数左边的
A:8,10
B:5,10
此时元素A和B的元素个数都为偶数个,则删除大的那个中位数右边的元素,删除小的那个中位数及它前面的元素,a=8,b=5,则A删掉10,B删掉它自己的中位数b=5
A:8
B:10
最后取小的那个数即可,即中位数=8,下面可以验证出是正确的
2,3,5,6,8,10,10,11,13,15
当a>b时类似推理即可
代码
#include <stdio.h>
int MidSearch(int A[],int B[],int n)
{int s1,s2,d1,d2,m1,m2;s1=s2=0;d1=d2=n-1;while(s1!=d1 && s2!=d2){m1 = (s1 + d1)/2;m2 = (s2 + d2)/2;if(A[m1]==A[m2]){return A[m1];//满足条件:两个数组的中位数相等}if(A[m1]<A[m2]){//满足条件:a<bif((s1+s2)%2==0){ //若元素个数为奇数,这里注意数组下标从0开始s1=m1; //舍弃 A 中间点以前的部分且保留中间点d2=m2; //舍弃 B 中间点以后的部分且保留中间点}else{ //元素个数为偶数s1=m1+1;//舍弃 A 中间点及中间点以前部分d2=m2; //舍弃 B 中间点以后部分且保留中间点}}else{ //满足条件:a>bif((s1+s2)%2==0){ //若元素个数为奇数d1=m1; //舍弃 A 中间点以后的部分且保留中间点s2=m2; //舍弃 B 中间点以前的部分且保留中间点}else{ //元素个数为偶数d1=m1; //舍弃 A 中间点以后部分且保留中间点s2=m2+1;//舍弃 B 中间点及中间点以前部分}}}return A[s1]<B[s2]?A[s1]:B[s2];
}
int main()
{int A[] = {2,6,8,10,11};int B[] = {3,5,8,12,13};int mid = MidSearch(A,B,5);printf("mid = %d\n",mid);return 0;
}
mid = 8