该题难度级别为困难,单其实也不难,就是考虑的情况比较多,略微繁琐,读题两个正序数组的中位数,显而易见我们需要将两个数组合成一个数组,再去取这个新数组的中位数,那么经常刷算法的应该知道对两个有序数组进行重排用归并排序算法即可,而本题只需要排一半即可,代码如下:
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int totalLength= nums1.length+ nums2.length;
// 判断总长度是奇数还是偶数,奇数的话中位数去中间的一个即可,偶数的话取靠中间的两个的平均值
boolean ou=totalLength%2==0;
// 中间的数是第几个,下标则为mid-1;
int mid=(totalLength+1)/2;
// 数组长度为零的情况
if(nums1.length==0){
if(ou){
double arr1=nums2[mid-1];
double arr2=nums2[mid];
return (arr1+arr2)/2;
}else {
return nums2[mid-1];
}
}else if(nums2.length==0){
if(ou){
double arr1=nums1[mid-1];
double arr2=nums1[mid];
return (arr1+arr2)/2;
}else {
return nums1[mid-1];
}
}
// 新数组
int[] arr=new int[mid+1];
// 两数组的起始下标
int index1=0;
int index2=0;
// 各取一个数待比较,考虑到可能有一个数组会全部被轮询完,所以用变量保存
int number1=nums1[index1];
int number2=nums2[index2];
for(int i=0;i<arr.length;i++){
// 保存更小的数,更小的下标前移
if(number1<number2){
arr[i]=number1;
index1++;
// 已轮询完,将另一个数组的剩下部分补充到新数组里
if(index1>=nums1.length){
for(int j=i+1;j<arr.length;j++){
arr[j]=nums2[index2];
index2++;
}
return getResult(ou,arr,mid);
}else{
// 未轮询完,更新待比较数
number1=nums1[index1];
}
}else{
arr[i]=nums2[index2];
index2++;
if(index2>=nums2.length){
for(int j=i+1;j<arr.length;j++){
arr[j]=nums1[index1];
index1++;
}
return getResult(ou,arr,mid);
}else{
number2=nums2[index2];
}
}
}
return getResult(ou,arr,mid);
}
// 从最终数组里取结果
private double getResult(boolean ou,int[] arr,int mid){
if(ou){
double arr1=arr[mid-1];
double arr2=arr[mid];
return (arr1+arr2)/2;
}else {
return arr[mid-1];
}
}
其实最多只需保存中间两个数即可,但为了看着简洁清晰,用了数组保存。