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.
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
解析:这题要求时间复杂度为log(m+n),按照传统思路绝壁不行,所以这里需要思考一下。题目所给的是two sorted arrays,那我们可以假设这两个数组都为非降序,现在让我们来解出中位数,首先中位数的值跟两数组长度之和有关,长度为奇数,取中间,为偶数,取中间两值平均值,其次由于数组是有序的,故我们求其中位数时可以转化为求第k小数问题,例如给定A=[1,3],B=[2,4],其中位数易知为2.5,怎么算呢?两数组长度之和为4,我们要求中位数须求得其第2和第3位数字是多少,当求第2位数字时,我们需要对2进行二分(以判断第2位数字究竟在哪个数组中),对2二分得1(即求两个数组中对应的第1小数),我们发现A[1-1]<B[1-1](注意:我们求某位数,但是数组下标从零开始,故减一),那么第2个数肯定不在数组A[1-1]前,我们就要舍弃数组A[1-1]前一部分变成数组A’,求第2小数也就变成了求第1小数,通过对比A’[1-1]=3,而B[1-1]=2,那么对于两数组而言第2小数肯定就为2了,同理求得第3小数为3,解得中位数为(2+3)/2=2.5.
解法:①C++
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int m=nums1.size(),n=nums2.size();
//若m+n为奇数,相当于求两次中位数再除2,结果不变,为偶数,则相当于求中间两数均值
return (getkth(nums1,nums2,(m+n+1)/2)+getkth(nums1,nums2,(m+n+2)/2))/2.0;
}
double getkth(vector<int> A,vector<int> B,int k){
if(A.size()>B.size()) return getkth(B,A,k); //为方便计算第k小数,须保证前者长度小于后者长度
if(A.size()==0) return B[k-1]; //A数组不存在第k小数,那么必然存在于B数组
if(B.size()==0) return A[k-1];
if(k==1) return min(A[0],B[0]); //若求第1小数,则需取两数组头数较小值即可
int la=min(k/2,(int)(A.size())),lb=k-la; //min的作用是考虑到A数组长度可能没有达到k/2,防止越界
if(A[la-1]>B[lb-1]) return getkth(A,vector<int>(B.begin()+lb,B.end()),k-lb); //舍弃B[lb-1]及其之前的数,更新k
else if(A[la-1]<B[lb-1]) return getkth(vector<int>(A.begin()+la,A.end()),B,k-la);
else return A[la-1]; //若相等,则返回其中一个即可
}
②Java
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m=nums1.length,n=nums2.length;
return (getkth(nums1,m,0,nums2,n,0,(m+n+1)/2)+getkth(nums1,m,0,nums2,n,0,(m+n+2)/2))/2.0;
}
//m,n为数组A和B的长度,a,b为数组A和B的头部位置
private double getkth(int[] A,int m,int a,int[] B,int n,int b,int k){
if(a==m) return B[b+k-1];
if(b==n) return A[a+k-1];
if(m>n) return getkth(B,n,b,A,m,a,k);
if(k==1) return Math.min(A[a],B[b]);
int la=Math.min(A.length-a,k/2),lb=k-la;
if(A[a+la-1]>B[b+lb-1]) return getkth(A,m,a,B,n,b+lb,k-lb);
else if(A[a+la-1]<B[b+lb-1]) return getkth(A,m,a+la,B,n,b,k-la);
else return A[a+la-1];
}
③python
def getKth(self, A, B, k):
lenA = len(A); lenB = len(B)
if lenA > lenB: return self.getKth(B, A, k)
if lenA == 0: return B[k - 1]
if k == 1: return min(A[0], B[0])
la = min(k/2, lenA); lb = k - la
if A[la - 1] <= B[lb - 1]:
return self.getKth(A[la:], B, lb)
else:
return self.getKth(A, B[lb:], la)
def findMedianSortedArrays(self, A, B):
lenA = len(A); lenB = len(B)
return (self.getKth(A, B, (lenA + lenB + 1)/2) + self.getKth(A, B, (lenA + lenB + 2)/2)) * 0.5