一,题目简述
There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
You may assume nums1 and nums2 cannot be both empty.
二分查找两个排序数组的中位数
规定了时间复杂度,所以限定我们只能用二分法查找
二,题目分析
首先什么是二分法,让我们回顾一下快速排序的过程:
时间复杂度:平均O(nlogn),最差O(n^2)
在快排中,我们只需要第一次遍历数组找到pilot对应的数值,把整个数组二分成两个小数组,再继续递归就能大大减少时间。
而这道题中,由于是两个已排序好的数组,所以不能用low==high这种简单的逻辑判断,而是抓住中位数和两个数组的联系做判断。
首先我们要确定中位数的概念,即在排好序的数组中,中位数左边的数和右边的数一样多,如果这个数组长度为偶数的话,中位数就是中间两个数的平均数。
在两个排序好的数组中也是如此,所以我们提取其中的有效信息:需要两个数组的长度,需要计算在中位数左边的数的长度,然后动态调整两个数组中备选中位数的位置
三,题目解答
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int n1 = nums1.length;
int n2 = nums2.length;
if(n1 > n2)
return findMedianSortedArrays(nums2, nums1);//保证nums1长度最小
int k = (n1+n2+1)/2;
int l = 0;
int r = n1;//初始值为nums1的中位数和nums2中对应的数
while(l < r){
int m1 = l+(r-l)/2;
int m2 = k-m1;
if(nums1[m1] < nums2[m2-1])//配合调整
l = m1+1;
else
r = m1;
}
int m1 = l;
int m2 = k-l;
int c1 = Math.max(m1<=0? Integer.MIN_VALUE : nums1[m1-1],
m2<=0? Integer.MIN_VALUE:nums2[m2-1]);
if((n1+n2)%2 == 1)//奇数时
return c1;
int c2 = Math.min(m1>=n1? Integer.MAX_VALUE : nums1[m1],
m2>=n2? Integer.MAX_VALUE:nums2[m2]);
return (c1+c2)*0.5;
}
}
m1和m2标志中位数的位置,所以m1+m2 = k = (n1+n2+1)/2, l和r调整数组1中位数的位置,通过l和r确定m1的位置。
取结果时,如果n1+n2是奇数,返回nums1[m1-1]和nums2[m2-1]最大的那个数即可
如果是偶数,返回nums1[m1-1]和nums2[m2-1]最大的那个数 与 nums1[m1]和nums2[m2]最小的那个数 的平均值
四,题目回忆
这道题的难点在于数组边界的判定,并且要二分法(我的理解二分法就是灵活运用数组的特性做比较)完成参数与参数之间的关系。