寻找两个正序数组的中位数
解法一:暴力解决
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int size=nums1.size()+nums2.size();
float a[size];
for(int i=0;i<nums1.size();i++)
{
a[i]=nums1[i];
}
for(int i=0;i<nums2.size();i++)
{
a[nums1.size()+i]=nums2[i];
}
sort(a,a+size);
if(size%2!=0) return a[size/2];
else return (a[size/2-1]+a[size/2])/2;
}
};
将提供的两个vector合并后排序输出中位数即可。
复杂度:O(m*n)
暴力解法显然不满足题目要求O(log (m+n)),题目要求利用二分搜索解答。
解法二:二分法:
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
if(nums1.size()>nums2.size())
{
return findMedianSortedArrays(nums2, nums1);
}
int low=0,high=nums1.size();
int k=(nums1.size()+nums2.size()+1)/2;
int size=nums1.size()+nums2.size();
int midA=0,midB=0;
while(low<=high)
{
midA=low+(high-low)/2;
midB=k-midA;
if(midA>0&&(nums1[midA-1]>nums2[midB]))
{
high=midA-1;
}
else if(midA<nums1.size()&&(nums1[midA]<nums2[midB-1]))
{
low=midA+1;
}
else
{
break;
}
}
int midleft=0,midright=0;
if(midA==0)
{
midleft=nums2[midB-1];
}
else if(midB==0)
{
midleft=nums1[midA-1];
}
else
{
midleft=max(nums1[midA-1],nums2[midB-1]);
}
if(size%2!=0)
{
return (double)(midleft);
}
if(midA==nums1.size())
{
midright=nums2[midB];
}
else if(midB==nums2.size())
{
midright=nums1[midA];
}
else
{
midright=min(nums1[midA],nums2[midB]);
}
return (double)(midleft+midright)/2;
}
};
使用二分查找一个数组的中位数分割线,则另一个数组的中位数也可以知道。
为了使得时间最短,所以搜索长度较短的数组。
当nums1[midA-1]>nums2[midB]
说明midA过大,应将区间向左移动;
当nums1[midA]<nums2[midB-1]
说明midA过小,应将区间向右移动。
最后按照midA和midB大小判断临界条件输出中位数。
复杂度:O(log (m+n))