📅  最后修改于: 2023-12-03 15:21:33.855000             🧑  作者: Mango
中位数是一组数据中居于中间位置的数值。在一个排好序的数组中,中位数是刚好在数组中间的一个数,如果数组长度为偶数,则中位数是中间两个数的平均数。
对于两个相同大小的排序数组,可以将其合并成一个有序数组,然后求出中位数。但这种方法需要O(n)的时间复杂度,不是最优解。
下面介绍一种时间复杂度为O(log n)的解法。
由于两个数组大小相同,先求出两个数组的中间数,然后比较它们的大小,如果相等,则中位数就是它们之一。如果第一个数组的中间数比第二个数组的中间数小,则中位数一定在第一个数组的右半部分和第二个数组的左半部分之间;否则中位数在第一个数组的左半部分和第二个数组的右半部分之间。
接着对两个部分分别递归进行上述过程,直到某个部分的长度为1或2时,求出中位数。
下面是Java代码实现:
public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
int len = nums1.length + nums2.length;
if (len % 2 == 1) {
return findKth(nums1, 0, nums2, 0, len / 2 + 1);
} else {
return (findKth(nums1, 0, nums2, 0, len / 2) + findKth(nums1, 0, nums2, 0, len / 2 + 1)) / 2.0;
}
}
private static int findKth(int[] nums1, int left1, int[] nums2, int left2, int k) {
if (left1 >= nums1.length) {
return nums2[left2 + k - 1];
}
if (left2 >= nums2.length) {
return nums1[left1 + k - 1];
}
if (k == 1) {
return Math.min(nums1[left1], nums2[left2]);
}
int mid1 = left1 + k / 2 - 1;
int mid2 = left2 + k / 2 - 1;
int num1 = mid1 >= nums1.length ? Integer.MAX_VALUE : nums1[mid1];
int num2 = mid2 >= nums2.length ? Integer.MAX_VALUE : nums2[mid2];
if (num1 < num2) {
return findKth(nums1, mid1 + 1, nums2, left2, k - k / 2);
} else {
return findKth(nums1, left1, nums2, mid2 + 1, k - k / 2);
}
}
下面是一个示例:
int[] nums1 = {1, 3, 5};
int[] nums2 = {2, 4, 6};
double median = findMedianSortedArrays(nums1, nums2);
System.out.println(median); // 输出3.5
注:上面代码中,findKth()方法中的k表示要求的第k个数,而不是下标。