在王道数据结构的课后算法题基础上改进的,感觉解法还是有点暴力=-=思路在注释里写清楚了
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
if(nums1Size>nums2Size){//统一代码,保证数组1长度<=数组2长度
int* p=nums1;nums1=nums2,nums2=p;
int tmp=nums1Size;nums1Size=nums2Size,nums2Size=tmp;
}
int l1=0,r1=nums1Size-1,l2=0,r2=nums2Size-1,mid1,mid2;
while(r1-l1>=2){//若短的数组只剩下两个,中位数可能为其平均值,故此处跳出循环,再用常规方式处理
mid1=(l1+r1)/2,mid2=(l2+r2)/2;
if(nums1[mid1]==nums2[mid2]){
//如果待比较数组均为奇数长度,则中位数为两个中值的均值,此处两均值相等,可返回任意一个
//如果两组数为一奇一偶,则奇数长度的mid对应的位置刚好是中位数
if((nums1Size%2)||(nums2Size%2))
return (double)nums2[mid2];
else{
//如果两组均为偶数长度,则对应的mid右侧比左侧元素多一个,需要比较两个mid右侧相邻元素的大小
//最终取两个相邻元素的较小值与下标为mid的值取平均数,得到中位数
int tmp= nums1[mid1+1]<nums2[mid2+1]?nums1[mid1+1]:nums2[mid2+1];
return (1.0*tmp+1.0*nums1[mid1])/2;
}
}
if(nums1[mid1]<nums2[mid2]){
//如果两组数据均为偶数长度,先各减去一个不影响结果的元素,讲其处理为奇数长度
if((!(nums1Size%2))&&(!(nums2Size%2))){
nums1Size-=1,nums2Size-=1,r2-=1,l1+=1;
}else{
//保证数组两侧裁去的长度相同,以短的(num1数组)为基准
r2=r2-(mid1-l1);
nums1Size-=(mid1-l1);
nums2Size-=(mid1-l1);
l1=mid1;
}
}else{
//同上
if((!(nums1Size%2))&&(!(nums2Size%2))){
nums1Size-=1,nums2Size-=1,r1-=1,l2+=1;
}else{
nums1Size-=(r1-mid1);
nums2Size-=(r1-mid1);
l2=l2+(r1-mid1);
r1=mid1;
}
}
}
//上述算法剪枝能力有限,如未在循环中得到中位数,达到边界条件跳出循环后,需要通过常规算法求解
int* f=(int*)malloc(sizeof(int)*(nums1Size+nums2Size));
int i=0;
while((l1<=r1)&&(l2<=r2)){
if(nums1[l1]<nums2[l2])f[i++]=nums1[l1++];
else f[i++]=nums2[l2++];
}
while(l1<=r1){
f[i++]=nums1[l1++];
}
while(l2<=r2){
f[i++]=nums2[l2++];
}
//依旧分奇数/偶数两种情况处理
if((nums1Size+nums2Size)%2)return (double)f[(nums1Size+nums2Size)/2];
else return (double)(f[(nums1Size+nums2Size)/2]*1.0+f[(nums1Size+nums2Size)/2-1]*1.0)/2;
}