15.7 2011年42题真题讲解

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<b
			if((s1+s2)%2==0){ //若元素个数为奇数,这里注意数组下标从0开始
				s1=m1;	//舍弃 A 中间点以前的部分且保留中间点
				d2=m2;	//舍弃 B 中间点以后的部分且保留中间点
			}else{		//元素个数为偶数
				s1=m1+1;//舍弃 A 中间点及中间点以前部分
				d2=m2;	//舍弃 B 中间点以后部分且保留中间点
			}
		}else{	//满足条件:a>b
			if((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
  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值