\[j = len(left\_part(nums2))=half\_len-i\tag{3}\\\mbox{由(1)和(2)可得}\\j = \frac{m+n+1}{2}-i\]
由于m和n都是已知,并且\(j\)可以由\(i\)推导出.
综上,此题就转化成了在\(nums1\)中找\(i\)的问题.
最高效的方法就是使用二分查找来找\(i\),初始条件为:
\[begin = 0\\end = m\\i = \frac{begin+end}{2}\]
找到\(nums[i]\)后,可以分成以下三种情况\(i>0,nums1[i-1]>nums2[j]\Rightarrow i\mbox{太大}\),在\([begin,i)\)内搜索
\(i
若上述两种情况都不成立,\(i\)符合条件,搜索停止
此时我们得到了\(i\)符合划分要求,接下来就是找中位数如果m+n为奇数,那么中位数为\(max(left\_part)\)
如果m+n为偶数,那么中位数为\(\frac{max(left\_part)+min(right\_part)}{2}\)
关于\(max(left\_part)\)的求解,如果\(i=0\),那么可知\(max(left\_part)=nums2[j-1]\)
如果\(j=0\),那么可知\(max(left\_part)=nums1[i-1]\)
一般情况,\(max(left\_part)=max(nums1[i-1],nums2[j-1])\)
同理可获得\(min(right\_part)\)
复杂度分析计算复杂度: \(O(\log(max(m,n)))\)
空间复杂度:\(O(1)\)
实现代码class Solution {
public:
double findMedianSortedArrays(vector& nums1, vector& nums2) {
int m = nums1.size();
int n = nums2.size();
if(m>n) // 确保m>n
{
return findMedianSortedArrays(nums2, nums1);
}
int halfLen = (m+n+1)/2;
int i,j,begin = 0,end= m;
double rval= 0.0;
while(begin<=end)
{
i = (begin+end)/2;
j = halfLen-i;
if(i
{
begin = i+1;
}
else if(i>0&&nums1[i-1]>nums2[j])
{
end = i-1;
}
else
{
int maxLeft,minRight;
if(i==0){
maxLeft = nums2[j-1];
}else if (j==0)
{
maxLeft = nums1[i-1];
}else{
maxLeft = nums1[i-1]>nums2[j-1]?nums1[i-1]:nums2[j-1];
}
if((m+n)%2==1)
{
rval = maxLeft;
break;
}
if(i==m)
{
minRight = nums2[j];
}else if (j==n)
{
minRight = nums1[i];
}else
{
minRight = nums1[i]
}
rval = ((double)(maxLeft+minRight))/2;
break;
}
}
return rval;
}
};