题解 | #在两个长度相等的排序数组中找到上中位数#
在两个长度相等的排序数组中找到上中位数
https://www.nowcoder.com/practice/6fbe70f3a51d44fa9395cfc49694404f
方法一:遍历法,因数列单调递增,故数列1从左往右,数列2从右往左,则中位数出现的情况共2种,一是中位数在数列1和2均存在,则只需在遍历时找到相等的值即可;二是中位数有且仅存在一个,该类型分3种情况,一是遍历刚开始,若数列1最小数大于数列2最大数,则数列2的最大值为中值;二是遍历过程中,若数列1由刚开始的小于数列2的情况变为大于数列2,则中位数可能为此时数列2的对应元素或者上一轮对比中数列1中的元素,只需比较即可,谁大谁为中值;三是遍历结束后,仍无数列1大于数列2元素的情况,则说明中位数为数列1的最大值。
方法二:二分递归法,首先同遍历法一样排除第一种情况,即中位数在数列1和2均存在,然后寻找第二类情况的中位数,采用二分递归法寻找答案,分2种情况,一是中值在二分的边界上和在边界值之间。当在边界上时,表明已经经过多轮检索,排除了除此时边界上的所有情况,则只需要比较两个数列中的边界值和相邻值,共4个元素,其中第二小的值为中位数;二是在边界值中间,则只需要让数列1的中间值和数列2的待比较值互相介于对方相邻元素的值之间,然后在比较二者大小,小的则为中位数,若不满足互相介于为对方相邻元素的值之间的条件,则需要根据二者大小更新边界,若数列1大于数列2的元素,则说明中位值在数列1此时中间值的左边,左边界值不变,中间值更新为右边界值,否则右边界值不变,左边界更新为中间值,进行下一轮查询,直到找到中值。
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* find median in two sorted array
* @param arr1 int整型一维数组 the array1
* @param arr1Len int arr1数组长度
* @param arr2 int整型一维数组 the array2
* @param arr2Len int arr2数组长度
* @return int整型
*/
int JudgeSecond(int BorderBelow1,int BorderBelow2,int BorderUp1,int BorderUp2)
{
int RetVal = -1;
if(BorderBelow1 >= BorderUp2)
{
RetVal = BorderUp2;
}
else
{
if(BorderBelow1 >= BorderBelow2)
{
RetVal = BorderBelow1;
}
else
{
RetVal = BorderBelow2;
}
}
if(BorderBelow2 >= BorderUp1)
{
RetVal = BorderUp1;
}
else
{
if(BorderBelow2 >= BorderBelow1)
{
RetVal = BorderBelow2;
}
else
{
RetVal = BorderBelow1;
}
}
return RetVal;
}
void LookMedium(int ThLow1,int ThHigh1,int* arr1, int* arr2,int Num,int* RetVal)
{
int index = ThLow1 + (ThHigh1- ThLow1) / 2;
printf("%d %d %d\n",index,ThHigh1,ThLow1);
if(*(arr1 + index) == *(arr2 + Num - 1 - index))
{
*RetVal = *(arr2 + Num - 1 - index);
return;
}
else
{
if(index == ThLow1)
{
*RetVal = JudgeSecond(*(arr1 + index),*(arr2 + Num - 1 - index - 1),*(arr1 + index + 1),*(arr2 + Num - 1 - index));
return;
}
else if(index == ThHigh1)
{
*RetVal = JudgeSecond(*(arr1 + index -1),*(arr2 + Num - 1 - index),*(arr1 + index),*(arr2 + Num - index));
return;
}
else
{
if(*(arr1 + index) > *(arr2 + Num - 1 - index))
{
if((*(arr1 + index) > *(arr2 + Num - 1 - index - 1) ) && (*(arr1 + index) < *(arr2 + Num - index) )&& (*(arr1 + index + 1) > *(arr2 + Num - 1 - index) ) && (*(arr1 + index - 1) < *(arr2 + Num - 1 - index) ))
{
*RetVal = *(arr2 + Num - 1 - index);
return;
}
else {
LookMedium(ThLow1,index,arr1,arr2,Num,RetVal);
}
}
else {
if((*(arr1 + index) > *(arr2 + Num - 1 - index - 1) ) && (*(arr1 + index) < *(arr2 + Num - index) )&& (*(arr1 + index + 1) > *(arr2 + Num - 1 - index) ) && (*(arr1 + index - 1) < *(arr2 + Num - 1 - index) ))
{
*RetVal = *(arr1 + index);
return;
}
else {
LookMedium(index,ThHigh1,arr1,arr2,Num,RetVal);
}
}
}
}
}
int findMedianinTwoSortedAray(int* arr1, int arr1Len, int* arr2, int arr2Len ) {
// write code here
int RetVal = -1;
#if 1
if(arr1Len == 1)
{
if(*arr1 > *arr2)
{
RetVal= *arr2;
}
else
{
RetVal= *arr1;
}
}
else {
LookMedium(0, arr1Len - 1,arr1,arr2,arr1Len,&RetVal);
}
#else
for(int i = 0; i < arr1Len; i++)
{
if(*(arr1+i) ==*(arr2+arr2Len -i -1))
{
RetVal = *(arr2+arr2Len -i -1);
break;
}
else if(*(arr1+i) >*(arr2+arr2Len -i -1))
{
if(i == 0)
{
RetVal = *(arr2+arr2Len -i -1);
break;
}
else {
if(*(arr1+ i -1) >*(arr2+arr2Len -i -1))
{
RetVal =*(arr1+ i -1) ;
break;
}
else {
RetVal = *(arr2+arr2Len -i -1);
printf("执行%d",i);
break;
}
}
}
else {
}
}
if(RetVal ==-1 )
{
RetVal = *(arr1+arr1Len-1);
}
#endif
return RetVal;
}

