方法一:暴力求解
1.合并数组 2.进行排序找到中位数
由于未利用数组自身有序的条件,时间复杂度高,用快排也需要的时间复杂度。
方法二:合并两个有序数组
1.利用归并排序关键步骤合并两个有序数组,找到中位数
时间复杂度:
方法三:二分查找
1.利用二分查找用一条分割线把两个数组分成左右两部分。
分割要求:(1)左右数量相等或者左边多一个(奇数情况)
(2)左边的元素小于右边的元素
2.整体偶数个:找到左边部分最大的,和右边部分最小的,求和除以2(实际除以2.0)
整体奇数个:找到左边部分最大的
时间复杂度:
思路:把较短的数组作为查找的数组,i=(left+right)/2;
其中i是nums1数组分割线右边的下标,同时是该数组分割线左边元素数量,对应下图15的下标。
由于左右数量相等或差一,我们可以用总数量+1除以2减去i就是nums2数组分割线左边的数量,
也就是j的值。
对nums1[i-1]和nums2[j]进行比较,小于等于则在[I+1,m]之间找,大于在[0,j-1]之间找,
直到left>right跳出while循环。
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {//二分查找
if(nums1.size()>nums2.size()){
return findMedianSortedArrays(nums2,nums1);//对较短的数组进行查找
}
int i,j,m,n,median1=0,median2=0,left,right,n1_left,n1_right,n2_left,n2_right;
m=nums1.size();
n=nums2.size();
left=0;right=m;//right初始为nums1的长度
while(left<=right){
// 前一部分包含 nums1[0 .. i-1] 和 nums2[0 .. j-1]
// 后一部分包含 nums1[i .. m-1] 和 nums2[j .. n-1]
i=(left+right)/2;//nums1数组分割线右边的下标,同时是该数组分割线左边元素数量
j=(m+n+1)/2-i; //nums2数组分割线右边的下标
n1_left= (i==0?INT_MIN:nums1[i-1]);//防止越界
n1_right= (i==m?INT_MAX:nums1[i]);
n2_left= (j==0?INT_MIN:nums2[j-1]);
n2_right= (j==n?INT_MAX:nums2[j]);
if(n1_left<=n2_right){
median1=max(n1_left,n2_left); // median1:前一部分的最大值
median2=min(n1_right,n2_right);// median2:后一部分的最小值
left=i+1;
}
else{
right=i-1;
}
}
return (m+n)%2==0?(median1+median2)/2.0:median1;//都是int类型需要除2.0
}
};