中文翻译如下:
有两个排好序的数组,找出其中位数。
思考:
两个数组num1和num2的数字范围有以下几种情况:
(1) (2)
(3) (4)
(5) (6)
考虑到三个地方这道题基本就可以被拿下了:
首先自然要用到二分搜索。我的想法是这样的,每次迭代要比较两个地方,一个是两个数组中间数(体现在程序中是nums1[mid1]<=nums2[mid2]),另一个是两个中位数的索引和(half>mid1+mid2),这样产生了四种情况,可以剪切掉不同的部分。
其次考虑到可能出现其中一个数组开始和结束索引相同。
最后两个数组的长度和可能是偶数或者奇数都要考虑到。
最后把程序贴出来如下:
public double finddMedianSortedArrays(int[] nums1, int[] nums2) {
final int total=nums1.length+nums2.length;
final boolean even=(((total&1)==1)?false:true);
final int half=total/2;
int index1Start=0,index1End=nums1.length;
int index2Start=0,index2End=nums2.length;
while(true){
if(index1Start>=index1End){
index2Start=half-index1Start;
break;
}
if(index2Start>=index2End){
index1Start=half-index2Start;
break;
}
int mid1=(index1Start+index1End)/2;
int mid2=(index2Start+index2End)/2;
if(nums1[mid1]<=nums2[mid2]){
if(half>mid1+mid2){
index1Start=mid1+1;
}else{
index2End=mid2;
}
}else{
if(half>mid1+mid2){
index2Start=mid2+1;
}else{
index1End=mid1;
}
}
}
if(even){
double num1;
if(index1Start<=0){
num1=nums2[index2Start-1];
}else if(index2Start<=0){
num1=nums1[index1Start-1];
}else{
num1=Math.max(nums1[index1Start-1], nums2[index2Start-1]);
}
double num2;
if(index1Start>=nums1.length){
num2=nums2[index2Start];
}else if(index2Start>=nums2.length){
num2=nums1[index1Start];
}else{
num2=Math.min(nums1[index1Start], nums2[index2Start]);
}
return (num1+num2)/2;
}else{
double num;
if(index1Start>=nums1.length){
num=nums2[index2Start];
}else if(index2Start>=nums2.length){
num=nums1[index1Start];
}else{
num=Math.min(nums1[index1Start], nums2[index2Start]);
}
return num;
}
}