- 使用的算法
二分查找、递归 - 核心思想
首先需要考虑两个数组总长度为奇数还是偶数,本题将两种可能合二为一,当为奇数时,则计算两遍;当为偶数时,则计算相邻两个数字之和的平均数。
int left = (l1+l2+1) / 2;
int right = (l1+l2+2) / 2;
其次是二分查找法,对于总长度len,中位数应为k = len/2,那么对于每个数组的中位数应为k/2,考虑数组角标和位数的对应关系,则中位数的角标为k/2-1.此时需要考虑当角标超界限时,应该将角标定义为数组最后一位。
Math.min(len1,k/2)-1;
Math.min(len2,k/2)-1;
此时出现三种情况,一组为空或k=1或k>1;为了确保为空的数组一定是第一组,进行一次判断,如果为T,则将两个数组对调。为空时,直接返回另一个数组当前指向的数字。
if(len1 > len2) return get(nums2,start2,end2,nums1,start1,end1,k);
当k=1时,则代表为当前中位数。
当k>1时,对两个数组当前指向的数字进行比较。比较原则如下:
k更新的原则是:每次将删除的数直接去掉。
- 详细代码
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
//确定两个数组长度
int l1 = nums1.length;
int l2 = nums2.length;
//解决总长度奇偶问题
int left = (l1+l2+1) / 2;
int right = (l1+l2+2) / 2;
return (get(nums1,0,l1-1,nums2,0,l2-1,left)+get(nums1,0,l1-1,nums2,0,l2-1,right))*0.5;
}
private int get(int[] nums1,int start1,int end1,int[] nums2,int start2,int end2,int k){
//获取当前数组长度
int len1 = end1 - start1 + 1;
int len2 = end2 - start2 + 1;
//维持len1最短
if(len1 > len2) return get(nums2,start2,end2,nums1,start1,end1,k);
//三种情况
if(len1 == 0) return nums2[start2 + k - 1];
if(k == 1) return Math.min(nums1[start1],nums2[start2]);
int add1 = start1 + Math.min(len1,k/2) - 1;
int add2 = start2 + Math.min(len2,k/2) - 1;
if(nums1[add1] > nums2[add2]){
return get(nums1,start1,end1,nums2,add2+1,end2,k-(add2 - start2 + 1));
}
else{
return get(nums1,add1+1,end1,nums2,start2,end2,k-(add1 - start1 + 1));
}
}
}