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)).
Example 1:
nums1 = [1, 3] nums2 = [2] The median is 2.0
Example 2:
nums1 = [1, 2] nums2 = [3, 4] The median is (2 + 3)/2 = 2.5
如果题目没有时间复杂度的要求,是一道非常简单的归并排序问题,只需要在进行merge的时候计一下数就可以了,效率为O(m+n)。
加了时间复杂度要求这道题其实是比较复杂的,首先我们可以把这道求中位数的问题转化为一个求第k小元素的问题,这个比较好理解,需要注意分为奇偶数讨论即可。然后需要了解一个比较重要的理论:如果A[k/2-1]<B[k/2-1],那么A[0]~A[k/2-1]一定在第k小的数的序列当中,可以用反证法证明。
有了这个理论,其实很明显可以进行递归编程了,但实际编程有几个问题或者说边界需要注意:
1、其中一个数组长度很小,小到小于k/2,这时候只能取min(k/2,length)
2、k=1时,即递归到求最小元素了,此时只需要返回当前两个数组的两个边界元素的最小值。
3、当一个数组已经被递归到过界,此时返回另一个数组的k-1项索引.
代码:
public double findMedianSortedArrays(int[] nums1, int[] nums2) { int length=nums1.length+nums2.length; if((length&1)==1) return findKth(nums1,0,nums2,0,length/2); else return (findKth(nums1,0,nums2,0,length/2-1)+findKth(nums1,0,nums2,0,length/2))/2; } public int findKth(int[] nums1,int abegin,int[] nums2,int bbegin,int k) { if(nums1.length>nums2.length) return findKth(nums2,bbegin,nums1,abegin,k); if(k==1) return Math.min(nums1[abegin],nums2[bbegin]); if(abegin> nums1.length-1) return nums2[k-1]; int indexa=Math.min(abegin+k/2,nums1.length-1); int indexb=bbegin+abegin+k-indexa-1; if(nums1[indexa]<nums2[indexb]) return findKth(nums1,abegin+indexa,nums2,bbegin,k-indexa); if(nums1[indexa]>nums2[indexb]) return findKth(nums1,abegin,nums2,bbegin+k/2,k/2); else return nums1[indexa]; }java写起来还是比较蛋疼的,因为不能直接截取数组,因此一定要对边界值考虑清楚,改了三四次才ac。