为了使用划分的方法解决这个问题,需要理解「中位数的作用是什么」。在统计中,中位数被用来将一个集合划分为两个长度相等的子集,其中一个子集中的元素总是大于另一个子集中的元素。如果理解了中位数的划分作用,就很接近答案了。首先,在任意位置 i 将 A 划分成两个部分 由于A 中有 m 个元素, 所以有 m+1种划分的方法(i∈[0,m])。采用同样的方式,在任意位置 j将 B 划分成两个部分将 lleft_A 和 left_B 放入一个集合,并将right_A 和 right_B 放入另一个集合。 再把这两个新的集合分别命名为 lleft_part 和 right_part为了简化分析,假设 A[i−1],B[j−1],A[i],B[j]总是存在。对于i=0、i=m、j=0、j=n 这样的临界条件,我们只需要规定 A[−1]=B[−1]=−∞,A[m]=B[n]=∞ 即可。这也是比较直观的:当一个数组不出现在前一部分时,对应的值为负无穷,就不会对前一部分的最大值产生影响;当一个数组不出现在后一部分时,对应的值为正无穷,就不会对后一部分的最小值产生影响。
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int length1=nums1.length,length2=nums2.length;
int totalLength=length1+length2;
if(totalLength%2==1){
int midIndex =totalLength/2;
double meidian = getKthElement(nums1,nums2,midIndex+1);
return meidian;
}else{
int midIndex1 = totalLength/2-1,midIndex2 = totalLength/2;
double meidian = (getKthElement(nums1,nums2,midIndex1+1)+getKthElement(nums1,nums2,midIndex2+1))/2.0;
return meidian;
}
}
public int getKthElement(int[] nums1,int[] nums2,int k){
int length1= nums1.length,length2=nums2.length;
int index1 =0,index2 =0;
int kthElement=0;
while(true){
if(index1==length1){
return nums2[index2+k-1];
}
if(index2 == length2){
return nums1[index1+k-1];
}
if(k==1){
return Math.min(nums1[index1],nums2[index2]);
}
int half =k/2;
int newIndex1 =Math.min(index1+half,length1)-1;
int newIndex2 =Math.min(index2+half,length2)-1;
int pivot1 = nums1[newIndex1], pivot2= nums2[newIndex2];
if(pivot1<=pivot2){
k=k-(newIndex1 -index1 +1);
index1=newIndex1+1;
}else{
k=k-(newIndex2-index2+1);
index2=newIndex2+1;
}
}
}
}