链接:https://leetcode.com/problems/median-of-two-sorted-arrays/description/
这道题主要是对时间复杂度有要求,因此,限制了解求的方式。
参考Discuss中的最高票答案,进行了很全面的分析,关键点在于对两个数组进行联合的二分法查找,由于两个数组都是有序的,因此,它们中位数是满足一个条件的:
(m+n+1)/2==i+j
(
m
+
n
+
1
)
/
2
==
i
+
j
i、j、m、n都是从1开始起算的下标。
同时,这里要注意应该将i置于长数组,j置于短数组,因为当i在短数组时,若处于边界,根据公式 j=(m+n+1)/2−i j = ( m + n + 1 ) / 2 − i 计算得出的 j j ,是一个负值,会出现错误。
源代码如下:
double findMedianSortedArrays(int A[], int m, int B[], int n)
{
if ( m > n ) return findMedianSortedArrays(B, n, A, m);//将两个数组调整输入顺序,将长数组置于后方
int minidx = 0, maxidx = m, i, j, num1, mid = (m + n + 1) >> 1, num2;//这里的>>运算符是除2的意思,位运算速度较快
while (minidx <= maxidx)
{
i = (minidx + maxidx) >> 1;
j = mid - i;
if (i < m && j>0 && B[j - 1] > A[i]) minidx = i+1;//二分法,当需要右移时,将中点+1赋给左边界
else if (i > 0 && j < n && B[j] < A[i - 1]) maxidx = i-1;//需要左移时,将中点-1赋给右边界
else
{
if (i == 0) num1 = B[j - 1];//i是0,则中位数在B中
else if (j == 0) num1 = A[i - 1];//j是0,则中位数在A中
else num1 = max(A[i - 1], B[j - 1]);//中位数是两个数组的分割点左元素的较大值
break;
}
}
if (((m + n) & 1)) return num1;//位运算求是否为奇数,如果是奇数,则中位数是惟一的
if (i == m) num2 = B[j];//中位数是两个的平均数,右侧中位数在i==m时,则稍大的数是在B中
else if (j == n) num2 = A[i];//同上
else num2 = min(A[i], B[j]);//另一个中位数是两个分割点右侧的较小值
return (num1 + num2) / 2.;//将int类型隐式转换为double
}
//测试代码:
int main()
{
int A[]{1,2,5,7}, B[]{3,4,8};
double c = findMedianSortedArrays(A,4,B,3);
cout << c << endl;
system("pause");
return 0;
}